* [PATCH 04/13] xen/arm: simplify dma_cache_maint
From: Christoph Hellwig @ 2019-09-02 13:03 UTC (permalink / raw)
To: Stefano Stabellini, Konrad Rzeszutek Wilk, gross, boris.ostrovsky
Cc: xen-devel, iommu, x86, linux-kernel, linux-arm-kernel
In-Reply-To: <20190902130339.23163-1-hch@lst.de>
Calculate the required operation in the caller, and pass it directly
instead of recalculating it for each page, and use simple arithmetics
to get from the physical address to Xen page size aligned chunks.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
arch/arm/xen/mm.c | 61 ++++++++++++++++-------------------------------
1 file changed, 21 insertions(+), 40 deletions(-)
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index 90574d89d0d4..2fde161733b0 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -35,64 +35,45 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order)
return __get_free_pages(flags, order);
}
-enum dma_cache_op {
- DMA_UNMAP,
- DMA_MAP,
-};
static bool hypercall_cflush = false;
-/* functions called by SWIOTLB */
-
-static void dma_cache_maint(dma_addr_t handle, unsigned long offset,
- size_t size, enum dma_data_direction dir, enum dma_cache_op op)
+/* buffers in highmem or foreign pages cannot cross page boundaries */
+static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op)
{
struct gnttab_cache_flush cflush;
- unsigned long xen_pfn;
- size_t left = size;
- xen_pfn = (handle >> XEN_PAGE_SHIFT) + offset / XEN_PAGE_SIZE;
- offset %= XEN_PAGE_SIZE;
+ cflush.a.dev_bus_addr = handle & XEN_PAGE_MASK;
+ cflush.offset = xen_offset_in_page(handle);
+ cflush.op = op;
do {
- size_t len = left;
-
- /* buffers in highmem or foreign pages cannot cross page
- * boundaries */
- if (len + offset > XEN_PAGE_SIZE)
- len = XEN_PAGE_SIZE - offset;
-
- cflush.op = 0;
- cflush.a.dev_bus_addr = xen_pfn << XEN_PAGE_SHIFT;
- cflush.offset = offset;
- cflush.length = len;
-
- if (op == DMA_UNMAP && dir != DMA_TO_DEVICE)
- cflush.op = GNTTAB_CACHE_INVAL;
- if (op == DMA_MAP) {
- if (dir == DMA_FROM_DEVICE)
- cflush.op = GNTTAB_CACHE_INVAL;
- else
- cflush.op = GNTTAB_CACHE_CLEAN;
- }
- if (cflush.op)
- HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1);
+ if (size + cflush.offset > XEN_PAGE_SIZE)
+ cflush.length = XEN_PAGE_SIZE - cflush.offset;
+ else
+ cflush.length = size;
+
+ HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1);
- offset = 0;
- xen_pfn++;
- left -= len;
- } while (left);
+ cflush.offset = 0;
+ cflush.a.dev_bus_addr += cflush.length;
+ size -= cflush.length;
+ } while (size);
}
static void __xen_dma_page_dev_to_cpu(struct device *hwdev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
- dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, DMA_UNMAP);
+ if (dir != DMA_TO_DEVICE)
+ dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
}
static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
- dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, DMA_MAP);
+ if (dir == DMA_FROM_DEVICE)
+ dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
+ else
+ dma_cache_maint(handle, size, GNTTAB_CACHE_CLEAN);
}
void __xen_dma_map_page(struct device *hwdev, struct page *page,
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 03/13] xen/arm: use dev_is_dma_coherent
From: Christoph Hellwig @ 2019-09-02 13:03 UTC (permalink / raw)
To: Stefano Stabellini, Konrad Rzeszutek Wilk, gross, boris.ostrovsky
Cc: x86, Julien Grall, linux-kernel, iommu, xen-devel,
linux-arm-kernel
In-Reply-To: <20190902130339.23163-1-hch@lst.de>
Use the dma-noncoherent dev_is_dma_coherent helper instead of the home
grown variant. Note that both are always initialized to the same
value in arch_setup_dma_ops.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
arch/arm/include/asm/dma-mapping.h | 6 ------
arch/arm/xen/mm.c | 12 ++++++------
arch/arm64/include/asm/dma-mapping.h | 9 ---------
3 files changed, 6 insertions(+), 21 deletions(-)
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index dba9355e2484..bdd80ddbca34 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -91,12 +91,6 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
}
#endif
-/* do not use this function in a driver */
-static inline bool is_device_dma_coherent(struct device *dev)
-{
- return dev->archdata.dma_coherent;
-}
-
/**
* arm_dma_alloc - allocate consistent memory for DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index d33b77e9add3..90574d89d0d4 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/cpu.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-noncoherent.h>
#include <linux/gfp.h>
#include <linux/highmem.h>
#include <linux/export.h>
@@ -99,7 +99,7 @@ void __xen_dma_map_page(struct device *hwdev, struct page *page,
dma_addr_t dev_addr, unsigned long offset, size_t size,
enum dma_data_direction dir, unsigned long attrs)
{
- if (is_device_dma_coherent(hwdev))
+ if (dev_is_dma_coherent(hwdev))
return;
if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
return;
@@ -112,7 +112,7 @@ void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
unsigned long attrs)
{
- if (is_device_dma_coherent(hwdev))
+ if (dev_is_dma_coherent(hwdev))
return;
if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
return;
@@ -123,7 +123,7 @@ void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
void __xen_dma_sync_single_for_cpu(struct device *hwdev,
dma_addr_t handle, size_t size, enum dma_data_direction dir)
{
- if (is_device_dma_coherent(hwdev))
+ if (dev_is_dma_coherent(hwdev))
return;
__xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
}
@@ -131,7 +131,7 @@ void __xen_dma_sync_single_for_cpu(struct device *hwdev,
void __xen_dma_sync_single_for_device(struct device *hwdev,
dma_addr_t handle, size_t size, enum dma_data_direction dir)
{
- if (is_device_dma_coherent(hwdev))
+ if (dev_is_dma_coherent(hwdev))
return;
__xen_dma_page_cpu_to_dev(hwdev, handle, size, dir);
}
@@ -159,7 +159,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
* memory and we are not able to flush the cache.
*/
return (!hypercall_cflush && (xen_pfn != bfn) &&
- !is_device_dma_coherent(dev));
+ !dev_is_dma_coherent(dev));
}
int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
index bdcb0922a40c..67243255a858 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -18,14 +18,5 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
return NULL;
}
-/*
- * Do not use this function in a driver, it is only provided for
- * arch/arm/mm/xen.c, which is used by arm64 as well.
- */
-static inline bool is_device_dma_coherent(struct device *dev)
-{
- return dev->dma_coherent;
-}
-
#endif /* __KERNEL__ */
#endif /* __ASM_DMA_MAPPING_H */
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 02/13] xen/arm: consolidate page-coherent.h
From: Christoph Hellwig @ 2019-09-02 13:03 UTC (permalink / raw)
To: Stefano Stabellini, Konrad Rzeszutek Wilk, gross, boris.ostrovsky
Cc: xen-devel, iommu, x86, linux-kernel, linux-arm-kernel
In-Reply-To: <20190902130339.23163-1-hch@lst.de>
Shared the duplicate arm/arm64 code in include/xen/arm/page-coherent.h.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm/include/asm/xen/page-coherent.h | 75 --------------------
arch/arm64/include/asm/xen/page-coherent.h | 75 --------------------
include/xen/arm/page-coherent.h | 80 ++++++++++++++++++++++
3 files changed, 80 insertions(+), 150 deletions(-)
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
index 602ac02f154c..27e984977402 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -1,77 +1,2 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_ARM_XEN_PAGE_COHERENT_H
-#define _ASM_ARM_XEN_PAGE_COHERENT_H
-
-#include <linux/dma-mapping.h>
-#include <asm/page.h>
#include <xen/arm/page-coherent.h>
-
-static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
-{
- return dma_direct_alloc(hwdev, size, dma_handle, flags, attrs);
-}
-
-static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
- void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
-{
- dma_direct_free(hwdev, size, cpu_addr, dma_handle, attrs);
-}
-
-static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
- unsigned long pfn = PFN_DOWN(handle);
-
- if (pfn_valid(pfn))
- dma_direct_sync_single_for_cpu(hwdev, handle, size, dir);
- else
- __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
-}
-
-static inline void xen_dma_sync_single_for_device(struct device *hwdev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
- unsigned long pfn = PFN_DOWN(handle);
- if (pfn_valid(pfn))
- dma_direct_sync_single_for_device(hwdev, handle, size, dir);
- else
- __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
-}
-
-static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
- dma_addr_t dev_addr, unsigned long offset, size_t size,
- enum dma_data_direction dir, unsigned long attrs)
-{
- unsigned long page_pfn = page_to_xen_pfn(page);
- unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
- unsigned long compound_pages =
- (1<<compound_order(page)) * XEN_PFN_PER_PAGE;
- bool local = (page_pfn <= dev_pfn) &&
- (dev_pfn - page_pfn < compound_pages);
-
- if (local)
- dma_direct_map_page(hwdev, page, offset, size, dir, attrs);
- else
- __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
-}
-
-static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir, unsigned long attrs)
-{
- unsigned long pfn = PFN_DOWN(handle);
- /*
- * Dom0 is mapped 1:1, while the Linux page can be spanned accross
- * multiple Xen page, it's not possible to have a mix of local and
- * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a
- * foreign mfn will always return false. If the page is local we can
- * safely call the native dma_ops function, otherwise we call the xen
- * specific function.
- */
- if (pfn_valid(pfn))
- dma_direct_unmap_page(hwdev, handle, size, dir, attrs);
- else
- __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
-}
-
-#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */
diff --git a/arch/arm64/include/asm/xen/page-coherent.h b/arch/arm64/include/asm/xen/page-coherent.h
index d88e56b90b93..27e984977402 100644
--- a/arch/arm64/include/asm/xen/page-coherent.h
+++ b/arch/arm64/include/asm/xen/page-coherent.h
@@ -1,77 +1,2 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_ARM64_XEN_PAGE_COHERENT_H
-#define _ASM_ARM64_XEN_PAGE_COHERENT_H
-
-#include <linux/dma-mapping.h>
-#include <asm/page.h>
#include <xen/arm/page-coherent.h>
-
-static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
-{
- return dma_direct_alloc(hwdev, size, dma_handle, flags, attrs);
-}
-
-static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
- void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
-{
- dma_direct_free(hwdev, size, cpu_addr, dma_handle, attrs);
-}
-
-static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
- unsigned long pfn = PFN_DOWN(handle);
-
- if (pfn_valid(pfn))
- dma_direct_sync_single_for_cpu(hwdev, handle, size, dir);
- else
- __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
-}
-
-static inline void xen_dma_sync_single_for_device(struct device *hwdev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
- unsigned long pfn = PFN_DOWN(handle);
- if (pfn_valid(pfn))
- dma_direct_sync_single_for_device(hwdev, handle, size, dir);
- else
- __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
-}
-
-static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
- dma_addr_t dev_addr, unsigned long offset, size_t size,
- enum dma_data_direction dir, unsigned long attrs)
-{
- unsigned long page_pfn = page_to_xen_pfn(page);
- unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
- unsigned long compound_pages =
- (1<<compound_order(page)) * XEN_PFN_PER_PAGE;
- bool local = (page_pfn <= dev_pfn) &&
- (dev_pfn - page_pfn < compound_pages);
-
- if (local)
- dma_direct_map_page(hwdev, page, offset, size, dir, attrs);
- else
- __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
-}
-
-static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir, unsigned long attrs)
-{
- unsigned long pfn = PFN_DOWN(handle);
- /*
- * Dom0 is mapped 1:1, while the Linux page can be spanned accross
- * multiple Xen page, it's not possible to have a mix of local and
- * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a
- * foreign mfn will always return false. If the page is local we can
- * safely call the native dma_ops function, otherwise we call the xen
- * specific function.
- */
- if (pfn_valid(pfn))
- dma_direct_unmap_page(hwdev, handle, size, dir, attrs);
- else
- __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
-}
-
-#endif /* _ASM_ARM64_XEN_PAGE_COHERENT_H */
diff --git a/include/xen/arm/page-coherent.h b/include/xen/arm/page-coherent.h
index 2ca9164a79bf..a840d6949a87 100644
--- a/include/xen/arm/page-coherent.h
+++ b/include/xen/arm/page-coherent.h
@@ -2,6 +2,9 @@
#ifndef _XEN_ARM_PAGE_COHERENT_H
#define _XEN_ARM_PAGE_COHERENT_H
+#include <linux/dma-mapping.h>
+#include <asm/page.h>
+
void __xen_dma_map_page(struct device *hwdev, struct page *page,
dma_addr_t dev_addr, unsigned long offset, size_t size,
enum dma_data_direction dir, unsigned long attrs);
@@ -13,4 +16,81 @@ void __xen_dma_sync_single_for_cpu(struct device *hwdev,
void __xen_dma_sync_single_for_device(struct device *hwdev,
dma_addr_t handle, size_t size, enum dma_data_direction dir);
+static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
+{
+ return dma_direct_alloc(hwdev, size, dma_handle, flags, attrs);
+}
+
+static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
+ void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
+{
+ dma_direct_free(hwdev, size, cpu_addr, dma_handle, attrs);
+}
+
+static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ unsigned long pfn = PFN_DOWN(handle);
+
+ if (pfn_valid(pfn))
+ dma_direct_sync_single_for_cpu(hwdev, handle, size, dir);
+ else
+ __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
+}
+
+static inline void xen_dma_sync_single_for_device(struct device *hwdev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ unsigned long pfn = PFN_DOWN(handle);
+ if (pfn_valid(pfn))
+ dma_direct_sync_single_for_device(hwdev, handle, size, dir);
+ else
+ __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
+}
+
+static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
+ dma_addr_t dev_addr, unsigned long offset, size_t size,
+ enum dma_data_direction dir, unsigned long attrs)
+{
+ unsigned long page_pfn = page_to_xen_pfn(page);
+ unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
+ unsigned long compound_pages =
+ (1<<compound_order(page)) * XEN_PFN_PER_PAGE;
+ bool local = (page_pfn <= dev_pfn) &&
+ (dev_pfn - page_pfn < compound_pages);
+
+ /*
+ * Dom0 is mapped 1:1, while the Linux page can span across
+ * multiple Xen pages, it's not possible for it to contain a
+ * mix of local and foreign Xen pages. So if the first xen_pfn
+ * == mfn the page is local otherwise it's a foreign page
+ * grant-mapped in dom0. If the page is local we can safely
+ * call the native dma_ops function, otherwise we call the xen
+ * specific function.
+ */
+ if (local)
+ dma_direct_map_page(hwdev, page, offset, size, dir, attrs);
+ else
+ __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
+}
+
+static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir, unsigned long attrs)
+{
+ unsigned long pfn = PFN_DOWN(handle);
+ /*
+ * Dom0 is mapped 1:1, while the Linux page can be spanned accross
+ * multiple Xen page, it's not possible to have a mix of local and
+ * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a
+ * foreign mfn will always return false. If the page is local we can
+ * safely call the native dma_ops function, otherwise we call the xen
+ * specific function.
+ */
+ if (pfn_valid(pfn))
+ dma_direct_unmap_page(hwdev, handle, size, dir, attrs);
+ else
+ __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
+}
+
#endif /* _XEN_ARM_PAGE_COHERENT_H */
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 01/13] xen/arm: use dma-noncoherent.h calls for xen-swiotlb cache maintainance
From: Christoph Hellwig @ 2019-09-02 13:03 UTC (permalink / raw)
To: Stefano Stabellini, Konrad Rzeszutek Wilk, gross, boris.ostrovsky
Cc: xen-devel, iommu, x86, linux-kernel, linux-arm-kernel
In-Reply-To: <20190902130339.23163-1-hch@lst.de>
Copy the arm64 code that uses the dma-direct/swiotlb helpers for DMA
on-coherent devices.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm/include/asm/device.h | 3 -
arch/arm/include/asm/xen/page-coherent.h | 72 +++++++++---------------
arch/arm/mm/dma-mapping.c | 8 +--
drivers/xen/swiotlb-xen.c | 20 -------
4 files changed, 28 insertions(+), 75 deletions(-)
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index f6955b55c544..c675bc0d5aa8 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -14,9 +14,6 @@ struct dev_archdata {
#endif
#ifdef CONFIG_ARM_DMA_USE_IOMMU
struct dma_iommu_mapping *mapping;
-#endif
-#ifdef CONFIG_XEN
- const struct dma_map_ops *dev_dma_ops;
#endif
unsigned int dma_coherent:1;
unsigned int dma_ops_setup:1;
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
index 2c403e7c782d..602ac02f154c 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -6,23 +6,37 @@
#include <asm/page.h>
#include <xen/arm/page-coherent.h>
-static inline const struct dma_map_ops *xen_get_dma_ops(struct device *dev)
-{
- if (dev && dev->archdata.dev_dma_ops)
- return dev->archdata.dev_dma_ops;
- return get_arch_dma_ops(NULL);
-}
-
static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
{
- return xen_get_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
+ return dma_direct_alloc(hwdev, size, dma_handle, flags, attrs);
}
static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
{
- xen_get_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
+ dma_direct_free(hwdev, size, cpu_addr, dma_handle, attrs);
+}
+
+static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ unsigned long pfn = PFN_DOWN(handle);
+
+ if (pfn_valid(pfn))
+ dma_direct_sync_single_for_cpu(hwdev, handle, size, dir);
+ else
+ __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
+}
+
+static inline void xen_dma_sync_single_for_device(struct device *hwdev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ unsigned long pfn = PFN_DOWN(handle);
+ if (pfn_valid(pfn))
+ dma_direct_sync_single_for_device(hwdev, handle, size, dir);
+ else
+ __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
}
static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
@@ -36,17 +50,8 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
bool local = (page_pfn <= dev_pfn) &&
(dev_pfn - page_pfn < compound_pages);
- /*
- * Dom0 is mapped 1:1, while the Linux page can span across
- * multiple Xen pages, it's not possible for it to contain a
- * mix of local and foreign Xen pages. So if the first xen_pfn
- * == mfn the page is local otherwise it's a foreign page
- * grant-mapped in dom0. If the page is local we can safely
- * call the native dma_ops function, otherwise we call the xen
- * specific function.
- */
if (local)
- xen_get_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
+ dma_direct_map_page(hwdev, page, offset, size, dir, attrs);
else
__xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
}
@@ -63,33 +68,10 @@ static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
* safely call the native dma_ops function, otherwise we call the xen
* specific function.
*/
- if (pfn_valid(pfn)) {
- if (xen_get_dma_ops(hwdev)->unmap_page)
- xen_get_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs);
- } else
+ if (pfn_valid(pfn))
+ dma_direct_unmap_page(hwdev, handle, size, dir, attrs);
+ else
__xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
}
-static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
- unsigned long pfn = PFN_DOWN(handle);
- if (pfn_valid(pfn)) {
- if (xen_get_dma_ops(hwdev)->sync_single_for_cpu)
- xen_get_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir);
- } else
- __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
-}
-
-static inline void xen_dma_sync_single_for_device(struct device *hwdev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
- unsigned long pfn = PFN_DOWN(handle);
- if (pfn_valid(pfn)) {
- if (xen_get_dma_ops(hwdev)->sync_single_for_device)
- xen_get_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir);
- } else
- __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
-}
-
#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index d42557ee69c2..738097396445 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1132,10 +1132,6 @@ static const struct dma_map_ops *arm_get_dma_map_ops(bool coherent)
* 32-bit DMA.
* Use the generic dma-direct / swiotlb ops code in that case, as that
* handles bounce buffering for us.
- *
- * Note: this checks CONFIG_ARM_LPAE instead of CONFIG_SWIOTLB as the
- * latter is also selected by the Xen code, but that code for now relies
- * on non-NULL dev_dma_ops. To be cleaned up later.
*/
if (IS_ENABLED(CONFIG_ARM_LPAE))
return NULL;
@@ -2363,10 +2359,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
set_dma_ops(dev, dma_ops);
#ifdef CONFIG_XEN
- if (xen_initial_domain()) {
- dev->archdata.dev_dma_ops = dev->dma_ops;
+ if (xen_initial_domain())
dev->dma_ops = xen_dma_ops;
- }
#endif
dev->archdata.dma_ops_setup = true;
}
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index ae1df496bf38..eee86cc7046b 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -557,11 +557,6 @@ xen_swiotlb_dma_mmap(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size,
unsigned long attrs)
{
-#ifdef CONFIG_ARM
- if (xen_get_dma_ops(dev)->mmap)
- return xen_get_dma_ops(dev)->mmap(dev, vma, cpu_addr,
- dma_addr, size, attrs);
-#endif
return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
}
@@ -574,21 +569,6 @@ xen_swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t handle, size_t size,
unsigned long attrs)
{
-#ifdef CONFIG_ARM
- if (xen_get_dma_ops(dev)->get_sgtable) {
-#if 0
- /*
- * This check verifies that the page belongs to the current domain and
- * is not one mapped from another domain.
- * This check is for debug only, and should not go to production build
- */
- unsigned long bfn = PHYS_PFN(dma_to_phys(dev, handle));
- BUG_ON (!page_is_ram(bfn));
-#endif
- return xen_get_dma_ops(dev)->get_sgtable(dev, sgt, cpu_addr,
- handle, size, attrs);
- }
-#endif
return dma_common_get_sgtable(dev, sgt, cpu_addr, handle, size, attrs);
}
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* swiotlb-xen cleanups v3
From: Christoph Hellwig @ 2019-09-02 13:03 UTC (permalink / raw)
To: Stefano Stabellini, Konrad Rzeszutek Wilk, gross, boris.ostrovsky
Cc: xen-devel, iommu, x86, linux-kernel, linux-arm-kernel
Hi Xen maintainers and friends,
please take a look at this series that cleans up the parts of swiotlb-xen
that deal with non-coherent caches.
Boris and Juergen, can you take a look at patch 8, which touches x86
a as well?
Changes since v2:
- further dma_cache_maint improvements
- split the previous patch 1 into 3 patches
Changes since v1:
- rewrite dma_cache_maint to be much simpler
- improve various comments and commit logs
- remove page-coherent.h entirely
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH net-next v3 1/3] net: dsa: mt7530: Convert to PHYLINK API
From: René van Dorst @ 2019-09-02 13:02 UTC (permalink / raw)
To: Sean Wang, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S . Miller, Matthias Brugger
Cc: Frank Wunderlich, netdev, linux-mips, Russell King,
René van Dorst, Russell King, linux-mediatek, John Crispin,
linux-arm-kernel
In-Reply-To: <20190902130226.26845-1-opensource@vdorst.com>
Convert mt7530 to PHYLINK API
Signed-off-by: René van Dorst <opensource@vdorst.com>
Tested-by: Frank Wunderlich <frank-w@public-files.de>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
---
v2->v3:
* No change
* Add tags acked-by and tested-by
v1->v2:
* Refactor "unsupported" phy_interface part in
mt7530_phylink_mac_validate() suggested by Russell King
* Report and return when phylink tries to use autoneg_inband in
mt7530_phylink_mac_config() suggested by Russell King
* Refactor port 6 setup in mt7530_phylink_mac_config()
rfc->v1:
* Renamed P5_MODE_* to P5_INTF_SEL_*. fits the function more
* Convert if-statement for speed bits to a switch suggested by
Daniel Santos
* Refactor flow_control pause bits and don't use state->link in
mt7530_phylink_mac_config() suggested by Russell King
* Move MAC tx/rx en/disable to mt7530_phylink_mac_link_up/down()
suggested by Russell King
* Always support PHY_INTERFACE_MODE_NA in mt7530_phylink_validate()
suggested by Russell King
* Added phylink_set_port_modes() in mt7530_phylink_validate() suggested
by Russell King
* Remove dev_err on the end of mt7530_phylink_mac_config() suggested by
Russell King
drivers/net/dsa/mt7530.c | 266 +++++++++++++++++++++++++++++----------
drivers/net/dsa/mt7530.h | 32 +++--
2 files changed, 211 insertions(+), 87 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index c48e29486b10..ecc13b57e619 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -13,7 +13,7 @@
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/of_platform.h>
-#include <linux/phy.h>
+#include <linux/phylink.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
@@ -633,63 +633,6 @@ mt7530_get_sset_count(struct dsa_switch *ds, int port, int sset)
return ARRAY_SIZE(mt7530_mib);
}
-static void mt7530_adjust_link(struct dsa_switch *ds, int port,
- struct phy_device *phydev)
-{
- struct mt7530_priv *priv = ds->priv;
-
- if (phy_is_pseudo_fixed_link(phydev)) {
- dev_dbg(priv->dev, "phy-mode for master device = %x\n",
- phydev->interface);
-
- /* Setup TX circuit incluing relevant PAD and driving */
- mt7530_pad_clk_setup(ds, phydev->interface);
-
- if (priv->id == ID_MT7530) {
- /* Setup RX circuit, relevant PAD and driving on the
- * host which must be placed after the setup on the
- * device side is all finished.
- */
- mt7623_pad_clk_setup(ds);
- }
- } else {
- u16 lcl_adv = 0, rmt_adv = 0;
- u8 flowctrl;
- u32 mcr = PMCR_USERP_LINK | PMCR_FORCE_MODE;
-
- switch (phydev->speed) {
- case SPEED_1000:
- mcr |= PMCR_FORCE_SPEED_1000;
- break;
- case SPEED_100:
- mcr |= PMCR_FORCE_SPEED_100;
- break;
- }
-
- if (phydev->link)
- mcr |= PMCR_FORCE_LNK;
-
- if (phydev->duplex) {
- mcr |= PMCR_FORCE_FDX;
-
- if (phydev->pause)
- rmt_adv = LPA_PAUSE_CAP;
- if (phydev->asym_pause)
- rmt_adv |= LPA_PAUSE_ASYM;
-
- lcl_adv = linkmode_adv_to_lcl_adv_t(
- phydev->advertising);
- flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
-
- if (flowctrl & FLOW_CTRL_TX)
- mcr |= PMCR_TX_FC_EN;
- if (flowctrl & FLOW_CTRL_RX)
- mcr |= PMCR_RX_FC_EN;
- }
- mt7530_write(priv, MT7530_PMCR_P(port), mcr);
- }
-}
-
static int
mt7530_cpu_port_enable(struct mt7530_priv *priv,
int port)
@@ -698,9 +641,6 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv,
mt7530_write(priv, MT7530_PVC_P(port),
PORT_SPEC_TAG);
- /* Setup the MAC by default for the cpu port */
- mt7530_write(priv, MT7530_PMCR_P(port), PMCR_CPUP_LINK);
-
/* Disable auto learning on the cpu port */
mt7530_set(priv, MT7530_PSC_P(port), SA_DIS);
@@ -731,9 +671,6 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
mutex_lock(&priv->reg_mutex);
- /* Setup the MAC for the user port */
- mt7530_write(priv, MT7530_PMCR_P(port), PMCR_USERP_LINK);
-
/* Allow the user port gets connected to the cpu port and also
* restore the port matrix if the port is the member of a certain
* bridge.
@@ -742,7 +679,7 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
priv->ports[port].enable = true;
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
priv->ports[port].pm);
- mt7530_port_set_status(priv, port, 1);
+ mt7530_port_set_status(priv, port, 0);
mutex_unlock(&priv->reg_mutex);
@@ -1232,10 +1169,10 @@ static int
mt7530_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
- int ret, i;
- u32 id, val;
- struct device_node *dn;
struct mt7530_dummy_poll p;
+ struct device_node *dn;
+ u32 id, val;
+ int ret, i;
/* The parent node of master netdev which holds the common system
* controller also is the container for two GMACs nodes representing
@@ -1305,6 +1242,8 @@ mt7530_setup(struct dsa_switch *ds)
val |= MHWTRAP_MANUAL;
mt7530_write(priv, MT7530_MHWTRAP, val);
+ priv->p6_interface = PHY_INTERFACE_MODE_NA;
+
/* Enable and reset MIB counters */
mt7530_mib_reset(ds);
@@ -1329,6 +1268,191 @@ mt7530_setup(struct dsa_switch *ds)
return 0;
}
+static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port,
+ unsigned int mode,
+ const struct phylink_link_state *state)
+{
+ struct mt7530_priv *priv = ds->priv;
+ u32 mcr_cur, mcr_new;
+
+ switch (port) {
+ case 0: /* Internal phy */
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ if (state->interface != PHY_INTERFACE_MODE_GMII)
+ return;
+ break;
+ /* case 5: Port 5 is not supported! */
+ case 6: /* 1st cpu port */
+ if (priv->p6_interface == state->interface)
+ break;
+
+ if (state->interface != PHY_INTERFACE_MODE_RGMII &&
+ state->interface != PHY_INTERFACE_MODE_TRGMII)
+ return;
+
+ /* Setup TX circuit incluing relevant PAD and driving */
+ mt7530_pad_clk_setup(ds, state->interface);
+
+ if (priv->id == ID_MT7530) {
+ /* Setup RX circuit, relevant PAD and driving on the
+ * host which must be placed after the setup on the
+ * device side is all finished.
+ */
+ mt7623_pad_clk_setup(ds);
+ }
+
+ priv->p6_interface = state->interface;
+ break;
+ default:
+ dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
+ return;
+ }
+
+ if (phylink_autoneg_inband(mode)) {
+ dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
+ __func__);
+ return;
+ }
+
+ mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
+ mcr_new = mcr_cur;
+ mcr_new &= ~(PMCR_FORCE_SPEED_1000 | PMCR_FORCE_SPEED_100 |
+ PMCR_FORCE_FDX | PMCR_TX_FC_EN | PMCR_RX_FC_EN);
+ mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
+ PMCR_BACKPR_EN | PMCR_FORCE_MODE | PMCR_FORCE_LNK;
+
+ switch (state->speed) {
+ case SPEED_1000:
+ mcr_new |= PMCR_FORCE_SPEED_1000;
+ break;
+ case SPEED_100:
+ mcr_new |= PMCR_FORCE_SPEED_100;
+ break;
+ }
+ if (state->duplex == DUPLEX_FULL) {
+ mcr_new |= PMCR_FORCE_FDX;
+ if (state->pause & MLO_PAUSE_TX)
+ mcr_new |= PMCR_TX_FC_EN;
+ if (state->pause & MLO_PAUSE_RX)
+ mcr_new |= PMCR_RX_FC_EN;
+ }
+
+ if (mcr_new != mcr_cur)
+ mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
+}
+
+static void mt7530_phylink_mac_link_down(struct dsa_switch *ds, int port,
+ unsigned int mode,
+ phy_interface_t interface)
+{
+ struct mt7530_priv *priv = ds->priv;
+
+ mt7530_port_set_status(priv, port, 0);
+}
+
+static void mt7530_phylink_mac_link_up(struct dsa_switch *ds, int port,
+ unsigned int mode,
+ phy_interface_t interface,
+ struct phy_device *phydev)
+{
+ struct mt7530_priv *priv = ds->priv;
+
+ mt7530_port_set_status(priv, port, 1);
+}
+
+static void mt7530_phylink_validate(struct dsa_switch *ds, int port,
+ unsigned long *supported,
+ struct phylink_link_state *state)
+{
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+
+ switch (port) {
+ case 0: /* Internal phy */
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ if (state->interface != PHY_INTERFACE_MODE_NA &&
+ state->interface != PHY_INTERFACE_MODE_GMII)
+ goto unsupported;
+ break;
+ /* case 5: Port 5 not supported! */
+ case 6: /* 1st cpu port */
+ if (state->interface != PHY_INTERFACE_MODE_NA &&
+ state->interface != PHY_INTERFACE_MODE_RGMII &&
+ state->interface != PHY_INTERFACE_MODE_TRGMII)
+ goto unsupported;
+ break;
+ default:
+ dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
+unsupported:
+ linkmode_zero(supported);
+ return;
+ }
+
+ phylink_set_port_modes(mask);
+ phylink_set(mask, Autoneg);
+
+ if (state->interface != PHY_INTERFACE_MODE_TRGMII) {
+ phylink_set(mask, 10baseT_Half);
+ phylink_set(mask, 10baseT_Full);
+ phylink_set(mask, 100baseT_Half);
+ phylink_set(mask, 100baseT_Full);
+ phylink_set(mask, 1000baseT_Half);
+ }
+
+ phylink_set(mask, 1000baseT_Full);
+
+ phylink_set(mask, Pause);
+ phylink_set(mask, Asym_Pause);
+
+ linkmode_and(supported, supported, mask);
+ linkmode_and(state->advertising, state->advertising, mask);
+}
+
+static int
+mt7530_phylink_mac_link_state(struct dsa_switch *ds, int port,
+ struct phylink_link_state *state)
+{
+ struct mt7530_priv *priv = ds->priv;
+ u32 pmsr;
+
+ if (port < 0 || port >= MT7530_NUM_PORTS)
+ return -EINVAL;
+
+ pmsr = mt7530_read(priv, MT7530_PMSR_P(port));
+
+ state->link = (pmsr & PMSR_LINK);
+ state->an_complete = state->link;
+ state->duplex = !!(pmsr & PMSR_DPX);
+
+ switch (pmsr & PMSR_SPEED_MASK) {
+ case PMSR_SPEED_10:
+ state->speed = SPEED_10;
+ break;
+ case PMSR_SPEED_100:
+ state->speed = SPEED_100;
+ break;
+ case PMSR_SPEED_1000:
+ state->speed = SPEED_1000;
+ break;
+ default:
+ state->speed = SPEED_UNKNOWN;
+ break;
+ }
+
+ state->pause &= ~(MLO_PAUSE_RX | MLO_PAUSE_TX);
+ if (pmsr & PMSR_RX_FC)
+ state->pause |= MLO_PAUSE_RX;
+ if (pmsr & PMSR_TX_FC)
+ state->pause |= MLO_PAUSE_TX;
+
+ return 1;
+}
+
static const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt7530_setup,
@@ -1337,7 +1461,6 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
.phy_write = mt7530_phy_write,
.get_ethtool_stats = mt7530_get_ethtool_stats,
.get_sset_count = mt7530_get_sset_count,
- .adjust_link = mt7530_adjust_link,
.port_enable = mt7530_port_enable,
.port_disable = mt7530_port_disable,
.port_stp_state_set = mt7530_stp_state_set,
@@ -1350,6 +1473,11 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
.port_vlan_prepare = mt7530_port_vlan_prepare,
.port_vlan_add = mt7530_port_vlan_add,
.port_vlan_del = mt7530_port_vlan_del,
+ .phylink_validate = mt7530_phylink_validate,
+ .phylink_mac_link_state = mt7530_phylink_mac_link_state,
+ .phylink_mac_config = mt7530_phylink_mac_config,
+ .phylink_mac_link_down = mt7530_phylink_mac_link_down,
+ .phylink_mac_link_up = mt7530_phylink_mac_link_up,
};
static const struct of_device_id mt7530_of_match[] = {
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index bfac90f48102..107dd04acede 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -198,26 +198,20 @@ enum mt7530_vlan_port_attr {
#define PMCR_FORCE_SPEED_100 BIT(2)
#define PMCR_FORCE_FDX BIT(1)
#define PMCR_FORCE_LNK BIT(0)
-#define PMCR_COMMON_LINK (PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
- PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \
- PMCR_TX_EN | PMCR_RX_EN | \
- PMCR_TX_FC_EN | PMCR_RX_FC_EN)
-#define PMCR_CPUP_LINK (PMCR_COMMON_LINK | PMCR_FORCE_MODE | \
- PMCR_FORCE_SPEED_1000 | \
- PMCR_FORCE_FDX | \
- PMCR_FORCE_LNK)
-#define PMCR_USERP_LINK PMCR_COMMON_LINK
-#define PMCR_FIXED_LINK (PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
- PMCR_FORCE_MODE | PMCR_TX_EN | \
- PMCR_RX_EN | PMCR_BACKPR_EN | \
- PMCR_BACKOFF_EN | \
- PMCR_FORCE_SPEED_1000 | \
- PMCR_FORCE_FDX | \
- PMCR_FORCE_LNK)
-#define PMCR_FIXED_LINK_FC (PMCR_FIXED_LINK | \
- PMCR_TX_FC_EN | PMCR_RX_FC_EN)
+#define PMCR_SPEED_MASK (PMCR_FORCE_SPEED_100 | \
+ PMCR_FORCE_SPEED_1000)
#define MT7530_PMSR_P(x) (0x3008 + (x) * 0x100)
+#define PMSR_EEE1G BIT(7)
+#define PMSR_EEE100M BIT(6)
+#define PMSR_RX_FC BIT(5)
+#define PMSR_TX_FC BIT(4)
+#define PMSR_SPEED_1000 BIT(3)
+#define PMSR_SPEED_100 BIT(2)
+#define PMSR_SPEED_10 0x00
+#define PMSR_SPEED_MASK (PMSR_SPEED_100 | PMSR_SPEED_1000)
+#define PMSR_DPX BIT(1)
+#define PMSR_LINK BIT(0)
/* Register for MIB */
#define MT7530_PORT_MIB_COUNTER(x) (0x4000 + (x) * 0x100)
@@ -423,6 +417,7 @@ struct mt7530_port {
* @ports: Holding the state among ports
* @reg_mutex: The lock for protecting among process accessing
* registers
+ * @p6_interface Holding the current port 6 interface
*/
struct mt7530_priv {
struct device *dev;
@@ -435,6 +430,7 @@ struct mt7530_priv {
struct gpio_desc *reset;
unsigned int id;
bool mcm;
+ phy_interface_t p6_interface;
struct mt7530_port ports[MT7530_NUM_PORTS];
/* protect among processes for registers access*/
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH net-next v3 3/3] net: dsa: mt7530: Add support for port 5
From: René van Dorst @ 2019-09-02 13:02 UTC (permalink / raw)
To: Sean Wang, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S . Miller, Matthias Brugger
Cc: Frank Wunderlich, netdev, linux-mips, Russell King,
René van Dorst, Russell King, linux-mediatek, John Crispin,
linux-arm-kernel
In-Reply-To: <20190902130226.26845-1-opensource@vdorst.com>
Adding support for port 5.
Port 5 can muxed/interface to:
- internal 5th GMAC of the switch; can be used as 2nd CPU port or as
extra port with an external phy for a 6th ethernet port.
- internal PHY of port 0 or 4; Used in most applications so that port 0
or 4 is the WAN port and interfaces with the 2nd GMAC of the SOC.
Signed-off-by: René van Dorst <opensource@vdorst.com>
Tested-by: Frank Wunderlich <frank-w@public-files.de>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
---
v2->v3:
* Change in mt7530_setup_port5() the port 5 setup message in to a debug
message. Suggested by David Miller
* Add tags acked-by and tested-by
v1->v2:
* Also report 1000base-x support for port 5 suggested by Russell King
* Reorder variable declaraiant in reverse christmas tree suggested by
Daved Miller
* Refactor phy-handle lookup for 2nd GMAC.
* Use of_mdio_parse_addr() instead of do it manualy suggested by
Florian Fainelli
* Refactor port 5 setup in mt7530_phylink_mac_config()
rfc->v1:
* Removed unnecessary info print suggested by Andrew Lunn
* Added support for MII mode for port 5
drivers/net/dsa/mt7530.c | 145 +++++++++++++++++++++++++++++++++++++--
drivers/net/dsa/mt7530.h | 29 ++++++++
2 files changed, 168 insertions(+), 6 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index ecc13b57e619..1d8d36de4d20 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -633,6 +633,77 @@ mt7530_get_sset_count(struct dsa_switch *ds, int port, int sset)
return ARRAY_SIZE(mt7530_mib);
}
+static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
+{
+ struct mt7530_priv *priv = ds->priv;
+ u8 tx_delay = 0;
+ int val;
+
+ mutex_lock(&priv->reg_mutex);
+
+ val = mt7530_read(priv, MT7530_MHWTRAP);
+
+ val |= MHWTRAP_MANUAL | MHWTRAP_P5_MAC_SEL | MHWTRAP_P5_DIS;
+ val &= ~MHWTRAP_P5_RGMII_MODE & ~MHWTRAP_PHY0_SEL;
+
+ switch (priv->p5_intf_sel) {
+ case P5_INTF_SEL_PHY_P0:
+ /* MT7530_P5_MODE_GPHY_P0: 2nd GMAC -> P5 -> P0 */
+ val |= MHWTRAP_PHY0_SEL;
+ /* fall through */
+ case P5_INTF_SEL_PHY_P4:
+ /* MT7530_P5_MODE_GPHY_P4: 2nd GMAC -> P5 -> P4 */
+ val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS;
+
+ /* Setup the MAC by default for the cpu port */
+ mt7530_write(priv, MT7530_PMCR_P(5), 0x56300);
+ break;
+ case P5_INTF_SEL_GMAC5:
+ /* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */
+ val &= ~MHWTRAP_P5_DIS;
+ break;
+ case P5_DISABLED:
+ interface = PHY_INTERFACE_MODE_NA;
+ break;
+ default:
+ dev_err(ds->dev, "Unsupported p5_intf_sel %d\n",
+ priv->p5_intf_sel);
+ goto unlock_exit;
+ }
+
+ /* Setup RGMII settings */
+ if (phy_interface_mode_is_rgmii(interface)) {
+ val |= MHWTRAP_P5_RGMII_MODE;
+
+ /* P5 RGMII RX Clock Control: delay setting for 1000M */
+ mt7530_write(priv, MT7530_P5RGMIIRXCR, CSR_RGMII_EDGE_ALIGN);
+
+ /* Don't set delay in DSA mode */
+ if (!dsa_is_dsa_port(priv->ds, 5) &&
+ (interface == PHY_INTERFACE_MODE_RGMII_TXID ||
+ interface == PHY_INTERFACE_MODE_RGMII_ID))
+ tx_delay = 4; /* n * 0.5 ns */
+
+ /* P5 RGMII TX Clock Control: delay x */
+ mt7530_write(priv, MT7530_P5RGMIITXCR,
+ CSR_RGMII_TXC_CFG(0x10 + tx_delay));
+
+ /* reduce P5 RGMII Tx driving, 8mA */
+ mt7530_write(priv, MT7530_IO_DRV_CR,
+ P5_IO_CLK_DRV(1) | P5_IO_DATA_DRV(1));
+ }
+
+ mt7530_write(priv, MT7530_MHWTRAP, val);
+
+ dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n",
+ val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface));
+
+ priv->p5_interface = interface;
+
+unlock_exit:
+ mutex_unlock(&priv->reg_mutex);
+}
+
static int
mt7530_cpu_port_enable(struct mt7530_priv *priv,
int port)
@@ -1169,7 +1240,10 @@ static int
mt7530_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
+ struct device_node *phy_node;
+ struct device_node *mac_np;
struct mt7530_dummy_poll p;
+ phy_interface_t interface;
struct device_node *dn;
u32 id, val;
int ret, i;
@@ -1260,6 +1334,40 @@ mt7530_setup(struct dsa_switch *ds)
mt7530_port_disable(ds, i);
}
+ /* Setup port 5 */
+ priv->p5_intf_sel = P5_DISABLED;
+ interface = PHY_INTERFACE_MODE_NA;
+
+ if (!dsa_is_unused_port(ds, 5)) {
+ priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
+ interface = of_get_phy_mode(ds->ports[5].dn);
+ } else {
+ /* Scan the ethernet nodes. look for GMAC1, lookup used phy */
+ for_each_child_of_node(dn, mac_np) {
+ if (!of_device_is_compatible(mac_np,
+ "mediatek,eth-mac"))
+ continue;
+
+ ret = of_property_read_u32(mac_np, "reg", &id);
+ if (ret < 0 || id != 1)
+ continue;
+
+ phy_node = of_parse_phandle(mac_np, "phy-handle", 0);
+ if (phy_node->parent == priv->dev->of_node->parent) {
+ interface = of_get_phy_mode(mac_np);
+ id = of_mdio_parse_addr(ds->dev, phy_node);
+ if (id == 0)
+ priv->p5_intf_sel = P5_INTF_SEL_PHY_P0;
+ if (id == 4)
+ priv->p5_intf_sel = P5_INTF_SEL_PHY_P4;
+ }
+ of_node_put(phy_node);
+ break;
+ }
+ }
+
+ mt7530_setup_port5(ds, interface);
+
/* Flush the FDB table */
ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
if (ret < 0)
@@ -1284,7 +1392,16 @@ static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port,
if (state->interface != PHY_INTERFACE_MODE_GMII)
return;
break;
- /* case 5: Port 5 is not supported! */
+ case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
+ if (priv->p5_interface == state->interface)
+ break;
+ if (!phy_interface_mode_is_rgmii(state->interface) &&
+ state->interface != PHY_INTERFACE_MODE_MII &&
+ state->interface != PHY_INTERFACE_MODE_GMII)
+ return;
+
+ mt7530_setup_port5(ds, state->interface);
+ break;
case 6: /* 1st cpu port */
if (priv->p6_interface == state->interface)
break;
@@ -1324,6 +1441,10 @@ static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port,
mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
PMCR_BACKPR_EN | PMCR_FORCE_MODE | PMCR_FORCE_LNK;
+ /* Are we connected to external phy */
+ if (port == 5 && dsa_is_user_port(ds, 5))
+ mcr_new |= PMCR_EXT_PHY;
+
switch (state->speed) {
case SPEED_1000:
mcr_new |= PMCR_FORCE_SPEED_1000;
@@ -1379,7 +1500,13 @@ static void mt7530_phylink_validate(struct dsa_switch *ds, int port,
state->interface != PHY_INTERFACE_MODE_GMII)
goto unsupported;
break;
- /* case 5: Port 5 not supported! */
+ case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
+ if (state->interface != PHY_INTERFACE_MODE_NA &&
+ !phy_interface_mode_is_rgmii(state->interface) &&
+ state->interface != PHY_INTERFACE_MODE_MII &&
+ state->interface != PHY_INTERFACE_MODE_GMII)
+ goto unsupported;
+ break;
case 6: /* 1st cpu port */
if (state->interface != PHY_INTERFACE_MODE_NA &&
state->interface != PHY_INTERFACE_MODE_RGMII &&
@@ -1396,15 +1523,21 @@ static void mt7530_phylink_validate(struct dsa_switch *ds, int port,
phylink_set_port_modes(mask);
phylink_set(mask, Autoneg);
- if (state->interface != PHY_INTERFACE_MODE_TRGMII) {
+ if (state->interface == PHY_INTERFACE_MODE_TRGMII) {
+ phylink_set(mask, 1000baseT_Full);
+ } else {
phylink_set(mask, 10baseT_Half);
phylink_set(mask, 10baseT_Full);
phylink_set(mask, 100baseT_Half);
phylink_set(mask, 100baseT_Full);
- phylink_set(mask, 1000baseT_Half);
- }
- phylink_set(mask, 1000baseT_Full);
+ if (state->interface != PHY_INTERFACE_MODE_MII) {
+ phylink_set(mask, 1000baseT_Half);
+ phylink_set(mask, 1000baseT_Full);
+ if (port == 5)
+ phylink_set(mask, 1000baseX_Full);
+ }
+ }
phylink_set(mask, Pause);
phylink_set(mask, Asym_Pause);
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 107dd04acede..ccb9da8cad0d 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -186,6 +186,7 @@ enum mt7530_vlan_port_attr {
/* Register for port MAC control register */
#define MT7530_PMCR_P(x) (0x3000 + ((x) * 0x100))
#define PMCR_IFG_XMIT(x) (((x) & 0x3) << 18)
+#define PMCR_EXT_PHY BIT(17)
#define PMCR_MAC_MODE BIT(16)
#define PMCR_FORCE_MODE BIT(15)
#define PMCR_TX_EN BIT(14)
@@ -245,6 +246,7 @@ enum mt7530_vlan_port_attr {
/* Register for hw trap modification */
#define MT7530_MHWTRAP 0x7804
+#define MHWTRAP_PHY0_SEL BIT(20)
#define MHWTRAP_MANUAL BIT(16)
#define MHWTRAP_P5_MAC_SEL BIT(13)
#define MHWTRAP_P6_DIS BIT(8)
@@ -402,6 +404,30 @@ struct mt7530_port {
u16 pvid;
};
+/* Port 5 interface select definitions */
+enum p5_interface_select {
+ P5_DISABLED = 0,
+ P5_INTF_SEL_PHY_P0,
+ P5_INTF_SEL_PHY_P4,
+ P5_INTF_SEL_GMAC5,
+};
+
+static const char *p5_intf_modes(unsigned int p5_interface)
+{
+ switch (p5_interface) {
+ case P5_DISABLED:
+ return "DISABLED";
+ case P5_INTF_SEL_PHY_P0:
+ return "PHY P0";
+ case P5_INTF_SEL_PHY_P4:
+ return "PHY P4";
+ case P5_INTF_SEL_GMAC5:
+ return "GMAC5";
+ default:
+ return "unknown";
+ }
+}
+
/* struct mt7530_priv - This is the main data structure for holding the state
* of the driver
* @dev: The device pointer
@@ -418,6 +444,7 @@ struct mt7530_port {
* @reg_mutex: The lock for protecting among process accessing
* registers
* @p6_interface Holding the current port 6 interface
+ * @p5_intf_sel: Holding the current port 5 interface select
*/
struct mt7530_priv {
struct device *dev;
@@ -431,6 +458,8 @@ struct mt7530_priv {
unsigned int id;
bool mcm;
phy_interface_t p6_interface;
+ phy_interface_t p5_interface;
+ unsigned int p5_intf_sel;
struct mt7530_port ports[MT7530_NUM_PORTS];
/* protect among processes for registers access*/
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH net-next v3 0/3] net: dsa: mt7530: Convert to PHYLINK and add support for port 5
From: René van Dorst @ 2019-09-02 13:02 UTC (permalink / raw)
To: Sean Wang, Andrew Lunn, Vivien Didelot, Florian Fainelli,
David S . Miller, Matthias Brugger
Cc: Frank Wunderlich, netdev, linux-mips, Russell King,
René van Dorst, linux-mediatek, John Crispin,
linux-arm-kernel
1. net: dsa: mt7530: Convert to PHYLINK API
This patch converts mt7530 to PHYLINK API.
2. dt-bindings: net: dsa: mt7530: Add support for port 5
3. net: dsa: mt7530: Add support for port 5
These 2 patches adding support for port 5 of the switch.
v2->v3:
* Removed 'status = "okay"' lines in patch #2
* Change a port 5 setup message in a debug message in patch #3
* Added ack-by and tested-by tags
v1->v2:
* Mostly phylink improvements after review.
rfc -> v1:
* Mostly phylink improvements after review.
* Drop phy isolation patches. Adds no value for now.
René van Dorst (3):
net: dsa: mt7530: Convert to PHYLINK API
dt-bindings: net: dsa: mt7530: Add support for port 5
net: dsa: mt7530: Add support for port 5
.../devicetree/bindings/net/dsa/mt7530.txt | 214 ++++++++++
drivers/net/dsa/mt7530.c | 371 +++++++++++++++---
drivers/net/dsa/mt7530.h | 61 ++-
3 files changed, 573 insertions(+), 73 deletions(-)
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 01/11] asm-generic: add dma_zone_size
From: Christoph Hellwig @ 2019-09-02 13:01 UTC (permalink / raw)
To: Nicolas Saenz Julienne
Cc: Catalin Marinas, eric, linux-riscv, frowand.list,
Christoph Hellwig, m.szyprowski, linux-arch, f.fainelli, will,
devicetree, Arnd Bergmann, marc.zyngier, robh+dt,
linux-rpi-kernel, linux-arm-kernel, phill, mbrugger, linux-mm,
linux-kernel, iommu, wahrenst, akpm, Robin Murphy
In-Reply-To: <bdeda2206b751a1c6a8d2e0732186792282633c6.camel@suse.de>
On Fri, Aug 30, 2019 at 07:24:25PM +0200, Nicolas Saenz Julienne wrote:
> I'll be happy to implement it that way. I agree it's a good compromise.
>
> @Christoph, do you still want the patch where I create 'zone_dma_bits'? With a
> hardcoded ZONE_DMA it's not absolutely necessary. Though I remember you said it
> was a first step towards being able to initialize dma-direct's min_mask in
> meminit.
I do like the variable better than the current #define. I wonder if
really want a mask or a max_zone_dma_address like variable. So for this
series feel free to drop the patch. I'll see if I'll pick it up
later or if we can find some way to automatically propagate that
information from the zone initialization.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 3/7] iommu/arm-smmu: Add tlb_sync implementation hook
From: Robin Murphy @ 2019-09-02 13:00 UTC (permalink / raw)
To: Krishna Reddy
Cc: Timo Alho, Thierry Reding, Mikko Perttunen,
linux-kernel@vger.kernel.org, joro@8bytes.org,
will.deacon@arm.com, iommu@lists.linux-foundation.org,
Pritesh Raithatha, Thomas Zeng (SW-TEGRA), Sachin Nikam,
linux-tegra@vger.kernel.org, Yu-Huan Hsu, Juha Tukkinen,
Alexander Van Brunt, linux-arm-kernel@lists.infradead.org
In-Reply-To: <BYAPR12MB271010C629D8DD7AEC0123D4B3BD0@BYAPR12MB2710.namprd12.prod.outlook.com>
On 30/08/2019 23:49, Krishna Reddy wrote:
>>> + if (smmu->impl->tlb_sync) {
>>> + smmu->impl->tlb_sync(smmu, page, sync, status);
>
>> What I'd hoped is that rather than needing a hook for this, you could just override smmu_domain->tlb_ops from .init_context to wire up the alternate .sync method directly. That would save this extra level of indirection.
>
> Hi Robin, overriding tlb_ops->tlb_sync function is not enough here.
> There are direct references to arm_smmu_tlb_sync_context(), arm_smmu_tlb_sync_global() functions.
> In arm-smmu.c. we can replace these direct references with tlb_ops->tlb_sync() function except in one function arm_smmu_device_reset().
> When arm_smmu_device_reset() gets called, domains are not initialized and tlb_ops is not available.
> Should we add a new hook for arm_smmu_tlb_sync_global() or make this as a responsibility of impl->reset() hook as it gets
> called at the same place?
Ah, right, I'd forgotten about the TLB maintenance on reset. Looking
again, though, I think you might need to implement impl->reset anyway
for the sake of clearing GFSR correctly - since the value read from the
base instance technically may not match whatever bits might happen to be
set in the other instances - so I don't see any issue with just calling
nsmmu_tlb_sync() from there as well.
Robin.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 11/11] misc: pci_endpoint_test: Add LS1088a in pci_device_id table
From: Andrew Murray @ 2019-09-02 12:54 UTC (permalink / raw)
To: Xiaowei Bao
Cc: mark.rutland, roy.zang, lorenzo.pieralisi, arnd, devicetree,
jingoohan1, zhiqiang.hou, linuxppc-dev, linux-pci, linux-kernel,
kishon, minghuan.Lian, robh+dt, gregkh, linux-arm-kernel,
gustavo.pimentel, leoyang.li, shawnguo, mingkai.hu
In-Reply-To: <20190902031716.43195-12-xiaowei.bao@nxp.com>
On Mon, Sep 02, 2019 at 11:17:16AM +0800, Xiaowei Bao wrote:
> Add LS1088a in pci_device_id table so that pci-epf-test can be used
> for testing PCIe EP in LS1088a.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> v2:
> - No change.
> v3:
> - No change.
>
> drivers/misc/pci_endpoint_test.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
> index 6e208a0..d531951 100644
> --- a/drivers/misc/pci_endpoint_test.c
> +++ b/drivers/misc/pci_endpoint_test.c
> @@ -793,6 +793,7 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
> { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) },
> { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) },
> { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) },
> + { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x80c0) },
The Freescale PCI devices are the only devices in this table that don't
have a define for their device ID. I think a define should be created
for both of the device IDs above.
Thanks,
Andrew Murray
> { PCI_DEVICE_DATA(SYNOPSYS, EDDA, NULL) },
> { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
> .driver_data = (kernel_ulong_t)&am654_data
> --
> 2.9.5
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v4 01/10] KVM: arm64: Document PV-time interface
From: Andrew Jones @ 2019-09-02 12:52 UTC (permalink / raw)
To: Steven Price
Cc: Mark Rutland, Radim Krčmář, kvm, Suzuki K Pouloze,
Marc Zyngier, linux-doc, Russell King, linux-kernel, James Morse,
linux-arm-kernel, Catalin Marinas, Paolo Bonzini, Will Deacon,
kvmarm, Julien Thierry
In-Reply-To: <7f459290-9c39-cfba-c514-a07469ff120f@arm.com>
On Fri, Aug 30, 2019 at 04:25:08PM +0100, Steven Price wrote:
> On 30/08/2019 15:47, Andrew Jones wrote:
> > On Fri, Aug 30, 2019 at 09:42:46AM +0100, Steven Price wrote:
> >> Introduce a paravirtualization interface for KVM/arm64 based on the
> >> "Arm Paravirtualized Time for Arm-Base Systems" specification DEN 0057A.
> >>
> >> This only adds the details about "Stolen Time" as the details of "Live
> >> Physical Time" have not been fully agreed.
> >>
> >> User space can specify a reserved area of memory for the guest and
> >> inform KVM to populate the memory with information on time that the host
> >> kernel has stolen from the guest.
> >>
> >> A hypercall interface is provided for the guest to interrogate the
> >> hypervisor's support for this interface and the location of the shared
> >> memory structures.
> >>
> >> Signed-off-by: Steven Price <steven.price@arm.com>
> >> ---
> >> Documentation/virt/kvm/arm/pvtime.txt | 64 +++++++++++++++++++++++++
> >> Documentation/virt/kvm/devices/vcpu.txt | 14 ++++++
> >> 2 files changed, 78 insertions(+)
> >> create mode 100644 Documentation/virt/kvm/arm/pvtime.txt
> >>
> >> diff --git a/Documentation/virt/kvm/arm/pvtime.txt b/Documentation/virt/kvm/arm/pvtime.txt
> >> new file mode 100644
> >> index 000000000000..dda3f0f855b9
> >> --- /dev/null
> >> +++ b/Documentation/virt/kvm/arm/pvtime.txt
> >> @@ -0,0 +1,64 @@
> >> +Paravirtualized time support for arm64
> >> +======================================
> >> +
> >> +Arm specification DEN0057/A defined a standard for paravirtualised time
> >> +support for AArch64 guests:
> >> +
> >> +https://developer.arm.com/docs/den0057/a
> >> +
> >> +KVM/arm64 implements the stolen time part of this specification by providing
> >> +some hypervisor service calls to support a paravirtualized guest obtaining a
> >> +view of the amount of time stolen from its execution.
> >> +
> >> +Two new SMCCC compatible hypercalls are defined:
> >> +
> >> +PV_FEATURES 0xC5000020
> >> +PV_TIME_ST 0xC5000022
> >> +
> >> +These are only available in the SMC64/HVC64 calling convention as
> >> +paravirtualized time is not available to 32 bit Arm guests. The existence of
> >> +the PV_FEATURES hypercall should be probed using the SMCCC 1.1 ARCH_FEATURES
> >> +mechanism before calling it.
> >> +
> >> +PV_FEATURES
> >> + Function ID: (uint32) : 0xC5000020
> >> + PV_func_id: (uint32) : Either PV_TIME_LPT or PV_TIME_ST
> >
> > PV_TIME_LPT doesn't exist
>
> Thanks, will remove.
>
> >> + Return value: (int32) : NOT_SUPPORTED (-1) or SUCCESS (0) if the relevant
> >> + PV-time feature is supported by the hypervisor.
> >> +
> >> +PV_TIME_ST
> >> + Function ID: (uint32) : 0xC5000022
> >> + Return value: (int64) : IPA of the stolen time data structure for this
> >> + VCPU. On failure:
> >> + NOT_SUPPORTED (-1)
> >> +
> >> +The IPA returned by PV_TIME_ST should be mapped by the guest as normal memory
> >> +with inner and outer write back caching attributes, in the inner shareable
> >> +domain. A total of 16 bytes from the IPA returned are guaranteed to be
> >> +meaningfully filled by the hypervisor (see structure below).
> >> +
> >> +PV_TIME_ST returns the structure for the calling VCPU.
> >> +
> >> +Stolen Time
> >> +-----------
> >> +
> >> +The structure pointed to by the PV_TIME_ST hypercall is as follows:
> >> +
> >> + Field | Byte Length | Byte Offset | Description
> >> + ----------- | ----------- | ----------- | --------------------------
> >> + Revision | 4 | 0 | Must be 0 for version 0.1
> >> + Attributes | 4 | 4 | Must be 0
> >
> > The above fields don't appear to be exposed to userspace in anyway. How
> > will we handle migration from one KVM with one version of the structure
> > to another?
>
> Interesting question. User space does have access to them now it is
> providing the memory, but it's not exactly an easy method. In particular
> user space has no (simple) way of probing the kernel's supported version.
>
> I guess one solution would be to add an extra attribute on the VCPU
> which would provide the revision information. The current kernel would
> then reject any revision other than 0, but this could then be extended
> to support other revision numbers in the future.
>
> Although there's some logic in saying we could add the extra attribute
> when(/if) there is a new version. Future kernels would then be expected
> to use the current version unless user space explicitly set the new
> attribute.
>
> Do you feel this is something that needs to be addressed now, or can it
> be deferred until another version is proposed?
Assuming we'll want userspace to have the option of choosing version=0,
and that we're fine with version=0 being the implicit choice, when nothing
is selected, then I guess it can be left as is for now. If, OTOH, we just
want migration to fail when attempting to migrate to another host with
an incompatible stolen-time structure (i.e. version=0 is not selectable
on hosts that implement later versions), then we should expose the version
in some way now. Perhaps a VCPU's "PV config" should be described in a
set of pseudo registers?
>
> >> + Stolen time | 8 | 8 | Stolen time in unsigned
> >> + | | | nanoseconds indicating how
> >> + | | | much time this VCPU thread
> >> + | | | was involuntarily not
> >> + | | | running on a physical CPU.
> >> +
> >> +The structure will be updated by the hypervisor prior to scheduling a VCPU. It
> >> +will be present within a reserved region of the normal memory given to the
> >> +guest. The guest should not attempt to write into this memory. There is a
> >> +structure per VCPU of the guest.
> >
> > Should we provide a recommendation as to how that reserved memory is
> > provided? One memslot divided into NR_VCPUS subregions? Should the
> > reserved region be described to the guest kernel with DT/ACPI? Or
> > should userspace ensure the region is not within any DT/ACPI described
> > regions?
>
> I'm open to providing a recommendation, but I'm not entirely sure I know
> enough here to provide one.
>
> There is an obvious efficiency argument for minimizing memslots with the
> current code. But if someone has a reason for using multiple memslots
> then that's probably a good argument for implementing a memslot-caching
> kvm_put_user() rather than to be dis-recommended.
Actually even if a single memslot is used for all the PV structures for
all VCPUs, but it's separate from the slot(s) used for main memory, then
we'll likely see performance issues with memslot searches (even though
it's a binary search). This is because memslots already have caching. The
last used slot is stored in the memslots' lru_slot member (the "lru" name
is confusing, but it means "last used" somehow). This means we could get
thrashing on that slot cache if we're searching for the PV structure
memslot on each vcpu load after searching for the main memory slot on each
page fault.
>
> My assumption (and testing) has been with a single memslot divided into
> NR_VCPUS (or more accurately the number of VCPUs in the VM) subregions.
>
> For testing DT I've tested both methods: an explicit reserved region or
> just ensuring it's not in any DT described region. Both seem reasonable,
> but it might be easier to integrate into existing migration mechanisms
> if it's simply a reserved region (then the memory block of the guest is
> just as it always was).
>
> For ACPI the situation should be similar, but my testing has been with DT.
I also can't think of any reason why we'd have to describe it in DT/ACPI,
but I get this feeling that if we don't, then we'll hit some issue that
will make us wish we had...
Thanks,
drew
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC 7/9] dt-bindings: rtc: s3c: Convert S3C/Exynos RTC bindings to json-schema
From: Krzysztof Kozlowski @ 2019-09-02 12:47 UTC (permalink / raw)
To: Rob Herring
Cc: Mark Rutland, Alessandro Zummo, Alexandre Belloni,
Lars-Peter Clausen, Arnd Bergmann, devicetree,
open list:IIO SUBSYSTEM AND DRIVERS, Marek Szyprowski,
linux-kernel@vger.kernel.org, Tomasz Figa, linux-samsung-soc,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Peter Meerwald-Stadler, Hartmut Knaack, Olof Johansson,
open list:REAL TIME CLOCK (RTC) SUBSYSTEM, notify,
Jonathan Cameron, Paweł Chmiel
In-Reply-To: <CAL_JsqKCpKuc=-4UyWFFv_RenKuSJcr9cdSKjbkL8F1ni+VODw@mail.gmail.com>
On Mon, 26 Aug 2019 at 14:06, Rob Herring <robh+dt@kernel.org> wrote:
>
> On Fri, Aug 23, 2019 at 9:54 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >
> > Convert Samsung S3C/Exynos Real Time Clock bindings to DT schema format
> > using json-schema.
> >
> > Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
> > ---
> > .../devicetree/bindings/rtc/s3c-rtc.txt | 31 ------
> > .../devicetree/bindings/rtc/s3c-rtc.yaml | 95 +++++++++++++++++++
> > 2 files changed, 95 insertions(+), 31 deletions(-)
> > delete mode 100644 Documentation/devicetree/bindings/rtc/s3c-rtc.txt
> > create mode 100644 Documentation/devicetree/bindings/rtc/s3c-rtc.yaml
>
>
> > diff --git a/Documentation/devicetree/bindings/rtc/s3c-rtc.yaml b/Documentation/devicetree/bindings/rtc/s3c-rtc.yaml
> > new file mode 100644
> > index 000000000000..44b021812a83
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/rtc/s3c-rtc.yaml
> > @@ -0,0 +1,95 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/rtc/s3c-rtc.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Samsung S3C, S5P and Exynos Real Time Clock controller
> > +
> > +maintainers:
> > + - Krzysztof Kozlowski <krzk@kernel.org>
> > +
> > +# Select also deprecated compatibles (for finding deprecate usage)
> > +select:
> > + properties:
> > + compatible:
> > + items:
> > + - enum:
> > + - samsung,s3c2410-rtc
> > + - samsung,s3c2416-rtc
> > + - samsung,s3c2443-rtc
> > + - samsung,s3c6410-rtc
> > + # Deprecated, use samsung,s3c6410-rtc
> > + - samsung,exynos3250-rtc
>
> We've come up with a better way of doing this that doesn't need a
> custom 'select'. Add a 'oneOf' to compatible and add another entry:
>
> - const: samsung,exynos3250-rtc
> deprecated: true
>
> It's not implemented yet in the tool, but we'll keep the compatible
> for 'select' and otherwise drop schema marked deprecated.
OK
>
> > + required:
> > + - compatible
> > +
> > +properties:
> > + compatible:
> > + items:
> > + - enum:
>
> You can drop 'items' when there's only 1 entry.
Indeed.
>
> > + - samsung,s3c2410-rtc
> > + - samsung,s3c2416-rtc
> > + - samsung,s3c2443-rtc
> > + - samsung,s3c6410-rtc
> > + reg:
> > + maxItems: 1
> > +
> > + clocks:
> > + description:
> > + Must contain a list of phandle and clock specifier for the rtc
> > + clock and in the case of a s3c6410 compatible controller, also
> > + a source clock.
> > + minItems: 1
> > + maxItems: 2
> > +
> > + clock-names:
> > + description:
> > + Must contain "rtc" and for a s3c6410 compatible controller,
> > + a "rtc_src" sorted in the same order as the clocks property.
> > + oneOf:
> > + - items:
> > + - const: rtc
> > + - items:
> > + # TODO: This can be in any order matching clocks, how to express it?
>
> It shouldn't be in any order. Fix the dts files.
I see, other schemas also require specific ordering.
>
> > + - const: rtc
> > + - const: rtc_src
>
> You should drop all this and add an else clause below.
Yes
>
> > +
> > + interrupts:
> > + description:
> > + Two interrupt numbers to the cpu should be specified. First
> > + interrupt number is the rtc alarm interrupt and second interrupt number
> > + is the rtc tick interrupt. The number of cells representing a interrupt
> > + depends on the parent interrupt controller.
> > + minItems: 2
> > + maxItems: 2
> > +
> > +allOf:
> > + - if:
> > + properties:
> > + compatible:
> > + contains:
> > + enum:
> > + - samsung,s3c6410-rtc
> > + - samsung,exynos3250-rtc
> > +
> > + then:
> > + properties:
> > + clocks:
> > + minItems: 2
> > + maxItems: 2
> > + clock-names:
> > + items:
> > + - const: rtc
> > + - const: rtc_src
>
> Should be indented 2 more spaces.
Thanks for feedback.
Best regards,
Krzysztof
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 09/11] PCI: layerscape: Add EP mode support for ls1088a and ls2088a
From: Andrew Murray @ 2019-09-02 12:46 UTC (permalink / raw)
To: Xiaowei Bao
Cc: mark.rutland, roy.zang, lorenzo.pieralisi, arnd, devicetree,
jingoohan1, zhiqiang.hou, linuxppc-dev, linux-pci, linux-kernel,
kishon, minghuan.Lian, robh+dt, gregkh, linux-arm-kernel,
gustavo.pimentel, leoyang.li, shawnguo, mingkai.hu
In-Reply-To: <20190902031716.43195-10-xiaowei.bao@nxp.com>
On Mon, Sep 02, 2019 at 11:17:14AM +0800, Xiaowei Bao wrote:
> Add PCIe EP mode support for ls1088a and ls2088a, there are some
> difference between LS1 and LS2 platform, so refactor the code of
> the EP driver.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> v2:
> - This is a new patch for supporting the ls1088a and ls2088a platform.
> v3:
> - Adjust the some struct assignment order in probe function.
>
> drivers/pci/controller/dwc/pci-layerscape-ep.c | 72 +++++++++++++++++++-------
> 1 file changed, 53 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index 5f0cb99..723bbe5 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -20,27 +20,29 @@
>
> #define PCIE_DBI2_OFFSET 0x1000 /* DBI2 base address*/
>
> -struct ls_pcie_ep {
> - struct dw_pcie *pci;
> - struct pci_epc_features *ls_epc;
> +#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
> +
> +struct ls_pcie_ep_drvdata {
> + u32 func_offset;
> + const struct dw_pcie_ep_ops *ops;
> + const struct dw_pcie_ops *dw_pcie_ops;
> };
>
> -#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
> +struct ls_pcie_ep {
> + struct dw_pcie *pci;
> + struct pci_epc_features *ls_epc;
> + const struct ls_pcie_ep_drvdata *drvdata;
> +};
>
> static int ls_pcie_establish_link(struct dw_pcie *pci)
> {
> return 0;
> }
>
> -static const struct dw_pcie_ops ls_pcie_ep_ops = {
> +static const struct dw_pcie_ops dw_ls_pcie_ep_ops = {
> .start_link = ls_pcie_establish_link,
> };
>
> -static const struct of_device_id ls_pcie_ep_of_match[] = {
> - { .compatible = "fsl,ls-pcie-ep",},
> - { },
> -};
> -
> static const struct pci_epc_features*
> ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
> {
> @@ -87,10 +89,39 @@ static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
> }
> }
>
> -static const struct dw_pcie_ep_ops pcie_ep_ops = {
> +static unsigned int ls_pcie_ep_func_conf_select(struct dw_pcie_ep *ep,
> + u8 func_no)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> + struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
> +
> + WARN_ON(func_no && !pcie->drvdata->func_offset);
> + return pcie->drvdata->func_offset * func_no;
> +}
> +
> +static const struct dw_pcie_ep_ops ls_pcie_ep_ops = {
> .ep_init = ls_pcie_ep_init,
> .raise_irq = ls_pcie_ep_raise_irq,
> .get_features = ls_pcie_ep_get_features,
> + .func_conf_select = ls_pcie_ep_func_conf_select,
> +};
> +
> +static const struct ls_pcie_ep_drvdata ls1_ep_drvdata = {
> + .ops = &ls_pcie_ep_ops,
> + .dw_pcie_ops = &dw_ls_pcie_ep_ops,
> +};
> +
> +static const struct ls_pcie_ep_drvdata ls2_ep_drvdata = {
> + .func_offset = 0x20000,
> + .ops = &ls_pcie_ep_ops,
> + .dw_pcie_ops = &dw_ls_pcie_ep_ops,
> +};
> +
> +static const struct of_device_id ls_pcie_ep_of_match[] = {
> + { .compatible = "fsl,ls1046a-pcie-ep", .data = &ls1_ep_drvdata },
> + { .compatible = "fsl,ls1088a-pcie-ep", .data = &ls2_ep_drvdata },
> + { .compatible = "fsl,ls2088a-pcie-ep", .data = &ls2_ep_drvdata },
> + { },
This removes support for "fsl,ls-pcie-ep" - was that intentional? If you do
plan to drop it please make sure you explain why in the commit message. See
also my comments in your dt-binding patch.
Thanks,
Andrew Murray
> };
>
> static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie,
> @@ -103,7 +134,7 @@ static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie,
> int ret;
>
> ep = &pci->ep;
> - ep->ops = &pcie_ep_ops;
> + ep->ops = pcie->drvdata->ops;
>
> res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
> if (!res)
> @@ -142,20 +173,23 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
> if (!ls_epc)
> return -ENOMEM;
>
> - dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
> - pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
> - if (IS_ERR(pci->dbi_base))
> - return PTR_ERR(pci->dbi_base);
> + pcie->drvdata = of_device_get_match_data(dev);
>
> - pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET;
> pci->dev = dev;
> - pci->ops = &ls_pcie_ep_ops;
> - pcie->pci = pci;
> + pci->ops = pcie->drvdata->dw_pcie_ops;
>
> ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
>
> + pcie->pci = pci;
> pcie->ls_epc = ls_epc;
>
> + dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
> + pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
> + if (IS_ERR(pci->dbi_base))
> + return PTR_ERR(pci->dbi_base);
> +
> + pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET;
> +
> platform_set_drvdata(pdev, pcie);
>
> ret = ls_add_pcie_ep(pcie, pdev);
> --
> 2.9.5
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] arm64: use x22 to save boot exception level
From: Mark Rutland @ 2019-09-02 12:37 UTC (permalink / raw)
To: Andrew F. Davis
Cc: Nishanth Menon, Matthew Leach, Catalin Marinas, linux-kernel,
Tero Kristo, Will Deacon, linux-arm-kernel
In-Reply-To: <511d200c-9294-e562-5ba5-4f061965395d@ti.com>
On Fri, Aug 30, 2019 at 03:23:53PM -0400, Andrew F. Davis wrote:
> On 8/29/19 5:47 AM, Mark Rutland wrote:
> > On Wed, Aug 28, 2019 at 01:33:18PM -0400, Andrew F. Davis wrote:
> We are seeing is a write-back from L3 cache. Our bootloader writes the
> kernel image with caches on, then after turning off caching but before
> handing off to Linux it clean/invalidates all cache lines by set/way.
> This cleans out the L1/L2 but leaves dirty lines in L3. Our platform
> doesn't really have a good way to clean L3 as it only provides cache
> maintenance operations by VA, not by line, so we would need to clean
> every VA address manually..
Ensuring that the Image is clean to the PoC is required by the arm64
boot protocol, which states that maintenance by VA may be necessary in
the presence of a system cache. See:
https://www.kernel.org/doc/html/latest/arm64/booting.html
... which states:
| The MMU must be off. Instruction cache may be on or off. The address
| range corresponding to the loaded kernel image must be cleaned to the
| PoC. In the presence of a system cache or other coherent masters with
| caches enabled, this will typically require cache maintenance by VA
| rather than set/way operations.
Please fix your bootloader to meet this requirement. The kernel is not
in a position to fix this up, e.g. as while the MMU is off instruction
fetches could fetch stale data from the PoC.
You only need to clean the kernel Image to the PoC, rather than all of
memory, so you should be able to do that with a loop of DC CVAC
instructions covering the VA range of the kernel Image.
> Also want to point out, although this isn't a problem for most platforms
> what this code does here, with writing to a location as non-cacheable,
> is not architecturally safe as the running cores that do the reads have
> this section marked as cacheable when they read, therefor you have
> mismatched attributes. When this happens like this according to the ARM
> ARM we should do a cache invalidate after the write *and* before the
>
> I would like to work this fix from the U-Boot side also, but in parallel
> I would like to reduce the mismatched attributes as much as possible on
> the kernel side like done here. So yes, we still will have issue with
> __early_cpu_boot_status, but that only seems to be needed in the failure
> to boot case, I'd like to fix that up as well at some later point.
If you haven't cleaned the Image to the PoC, there's no guarantee that
any portion of it can be safely executed with the MMU off, so I don't
think that makes sense -- please fix your bootloader first.
I am aware that there are potential problems with mismatched attributes,
the primary issue here being unexpected-data-cache-hit. However, were
that to occur no amount of cache maintenance can save us in the presence
of a live cacheable alias. Practically speaking that's mainly a problem
for virtual environments.
Thanks,
Mark.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 05/11] dt-bindings: pci: layerscape-pci: add compatible strings for ls1088a and ls2088a
From: Andrew Murray @ 2019-09-02 12:31 UTC (permalink / raw)
To: Xiaowei Bao
Cc: mark.rutland, roy.zang, lorenzo.pieralisi, arnd, devicetree,
jingoohan1, zhiqiang.hou, linuxppc-dev, linux-pci, linux-kernel,
kishon, minghuan.Lian, robh+dt, gregkh, linux-arm-kernel,
gustavo.pimentel, leoyang.li, shawnguo, mingkai.hu
In-Reply-To: <20190902031716.43195-6-xiaowei.bao@nxp.com>
On Mon, Sep 02, 2019 at 11:17:10AM +0800, Xiaowei Bao wrote:
> Add compatible strings for ls1088a and ls2088a.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> v2:
> - No change.
> v3:
> - Use one valid combination of compatible strings.
>
> Documentation/devicetree/bindings/pci/layerscape-pci.txt | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt
> index e20ceaa..762ae41 100644
> --- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt
> +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt
> @@ -22,7 +22,9 @@ Required properties:
> "fsl,ls1043a-pcie"
> "fsl,ls1012a-pcie"
> EP mode:
> - "fsl,ls1046a-pcie-ep", "fsl,ls-pcie-ep"
> + "fsl,ls1046a-pcie-ep" "fsl,ls-pcie-ep"
> + "fsl,ls1088a-pcie-ep" "fsl,ls-pcie-ep"
> + "fsl,ls2088a-pcie-ep" "fsl,ls-pcie-ep"
This isn't consistent with "[PATCH v3 09/11] PCI: layerscape: Add EP mode..."
as that patch drops the fallback "fsl,ls-pcie-ep". Either the fallback must
be preserved in the driver, or you need to drop it here.
What if there are existing users that depend on the fallback?
(I'm also not sure if that comma should have been dropped).
Thanks,
Andrew Murray
> - reg: base addresses and lengths of the PCIe controller register blocks.
> - interrupts: A list of interrupt outputs of the controller. Must contain an
> entry for each entry in the interrupt-names property.
> --
> 2.9.5
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 2/9] x86: numa: check the node id consistently for x86
From: Yunsheng Lin @ 2019-09-02 12:25 UTC (permalink / raw)
To: Peter Zijlstra
Cc: dalias, linux-sh, catalin.marinas, dave.hansen, heiko.carstens,
linuxarm, jiaxun.yang, linux-mips, mwb, paulus, hpa, sparclinux,
chenhc, will, bp, linux-s390, ysato, mpe, x86, rppt, borntraeger,
dledford, mingo, jeffrey.t.kirsher, benh, jhogan, nfont, mattst88,
len.brown, gor, anshuman.khandual, ink, luto, tglx, naveen.n.rao,
linux-arm-kernel, rth, axboe, linuxppc-dev, linux-kernel, ralf,
tbogendoerfer, paul.burton, linux-alpha, cai, akpm, robin.murphy,
davem
In-Reply-To: <20190902072542.GN2369@hirez.programming.kicks-ass.net>
On 2019/9/2 15:25, Peter Zijlstra wrote:
> On Mon, Sep 02, 2019 at 01:46:51PM +0800, Yunsheng Lin wrote:
>> On 2019/9/1 0:12, Peter Zijlstra wrote:
>
>>> 1) because even it is not set, the device really does belong to a node.
>>> It is impossible a device will have magic uniform access to memory when
>>> CPUs cannot.
>>
>> So it means dev_to_node() will return either NUMA_NO_NODE or a
>> valid node id?
>
> NUMA_NO_NODE := -1, which is not a valid node number. It is also, like I
> said, not a valid device location on a NUMA system.
>
> Just because ACPI/BIOS is shit, doesn't mean the device doesn't have a
> node association. It just means we don't know and might have to guess.
How do we guess the device's location when ACPI/BIOS does not set it?
It seems dev_to_node() does not do anything about that and leave the
job to the caller or whatever function that get called with its return
value, such as cpumask_of_node().
>
>>> 2) is already true today, cpumask_of_node() requires a valid node_id.
>>
>> Ok, most of the user does check node_id before calling
>> cpumask_of_node(), but does a little different type of checking:
>>
>> 1) some does " < 0" check;
>> 2) some does "== NUMA_NO_NODE" check;
>> 3) some does ">= MAX_NUMNODES" check;
>> 4) some does "< 0 || >= MAX_NUMNODES || !node_online(node)" check.
>
> The one true way is:
>
> '(unsigned)node_id >= nr_node_ids'
I missed the magic of the "unsigned" in your previous reply.
>
>>> 3) is just wrong and increases overhead for everyone.
>>
>> Ok, cpumask_of_node() is also used in some critical path such
>> as scheduling, which may not need those checking, the overhead
>> is unnecessary.
>>
>> But for non-critical path such as setup or configuration path,
>> it better to have consistent checking, and also simplify the
>> user code that calls cpumask_of_node().
>>
>> Do you think it is worth the trouble to add a new function
>> such as cpumask_of_node_check(maybe some other name) to do
>> consistent checking?
>>
>> Or caller just simply check if dev_to_node()'s return value is
>> NUMA_NO_NODE before calling cpumask_of_node()?
>
> It is not a matter of convenience. The function is called
> cpumask_of_node(), when node < 0 || node >= nr_node_ids, it is not a
> valid node, therefore the function shouldn't return anything except an
> error.
what do you mean by error? What I can think is three type of errors:
1) return NULL, this way it seems cpumask_of_node() also leave the
job to the function that calls it.
2) cpu_none_mask, I am not sure what this means, maybe it means there
is no cpu on the same node with the device?
3) give a warning, stack dump, or even a BUG_ON?
I would prefer the second one, and implement the third one when the
CONFIG_DEBUG_PER_CPU_MAPS is selected.
Any suggestion?
>
> Also note that the CONFIG_DEBUG_PER_CPU_MAPS version of
> cpumask_of_node() already does this (although it wants the below fix).
Thanks for the note and example.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Applied "spi: ep93xx: Repair SPI CS lookup tables" to the spi tree
From: Mark Brown @ 2019-09-02 12:24 UTC (permalink / raw)
To: Alexander Sverdlin
Cc: linux-gpio, Linus Walleij, Lukasz Majewski, stable, linux-spi,
Hartley Sweeten, Mark Brown, Russell King, linux-arm-kernel
In-Reply-To: <20190831180402.10008-1-alexander.sverdlin@gmail.com>
The patch
spi: ep93xx: Repair SPI CS lookup tables
has been applied to the spi tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-5.4
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
From 4fbc485324d2975c54201091dfad0a7dd4902324 Mon Sep 17 00:00:00 2001
From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Date: Sat, 31 Aug 2019 20:04:02 +0200
Subject: [PATCH] spi: ep93xx: Repair SPI CS lookup tables
The actual device name of the SPI controller being registered on EP93xx is
"spi0" (as seen by gpiod_find_lookup_table()). This patch fixes all
relevant lookup tables and the following failure (seen on EDB9302):
ep93xx-spi ep93xx-spi.0: failed to register SPI master
ep93xx-spi: probe of ep93xx-spi.0 failed with error -22
Fixes: 1dfbf334f1236 ("spi: ep93xx: Convert to use CS GPIO descriptors")
Cc: stable@vger.kernel.org
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Lukasz Majewski <lukma@denx.de>
Link: https://lore.kernel.org/r/20190831180402.10008-1-alexander.sverdlin@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
---
arch/arm/mach-ep93xx/edb93xx.c | 2 +-
arch/arm/mach-ep93xx/simone.c | 2 +-
arch/arm/mach-ep93xx/ts72xx.c | 4 ++--
arch/arm/mach-ep93xx/vision_ep9307.c | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index 1f0da76a39de..7b7280c21ee0 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -103,7 +103,7 @@ static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
};
static struct gpiod_lookup_table edb93xx_spi_cs_gpio_table = {
- .dev_id = "ep93xx-spi.0",
+ .dev_id = "spi0",
.table = {
GPIO_LOOKUP("A", 6, "cs", GPIO_ACTIVE_LOW),
{ },
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
index e2658e22bba1..8a53b74dc4b2 100644
--- a/arch/arm/mach-ep93xx/simone.c
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -73,7 +73,7 @@ static struct spi_board_info simone_spi_devices[] __initdata = {
* v1.3 parts will still work, since the signal on SFRMOUT is automatic.
*/
static struct gpiod_lookup_table simone_spi_cs_gpio_table = {
- .dev_id = "ep93xx-spi.0",
+ .dev_id = "spi0",
.table = {
GPIO_LOOKUP("A", 1, "cs", GPIO_ACTIVE_LOW),
{ },
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 582e06e104fd..e0e1b11032f1 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -267,7 +267,7 @@ static struct spi_board_info bk3_spi_board_info[] __initdata = {
* goes through CPLD
*/
static struct gpiod_lookup_table bk3_spi_cs_gpio_table = {
- .dev_id = "ep93xx-spi.0",
+ .dev_id = "spi0",
.table = {
GPIO_LOOKUP("F", 3, "cs", GPIO_ACTIVE_LOW),
{ },
@@ -316,7 +316,7 @@ static struct spi_board_info ts72xx_spi_devices[] __initdata = {
};
static struct gpiod_lookup_table ts72xx_spi_cs_gpio_table = {
- .dev_id = "ep93xx-spi.0",
+ .dev_id = "spi0",
.table = {
/* DIO_17 */
GPIO_LOOKUP("F", 2, "cs", GPIO_ACTIVE_LOW),
diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c
index a88a1d807b32..cbcba3136d74 100644
--- a/arch/arm/mach-ep93xx/vision_ep9307.c
+++ b/arch/arm/mach-ep93xx/vision_ep9307.c
@@ -242,7 +242,7 @@ static struct spi_board_info vision_spi_board_info[] __initdata = {
};
static struct gpiod_lookup_table vision_spi_cs_gpio_table = {
- .dev_id = "ep93xx-spi.0",
+ .dev_id = "spi0",
.table = {
GPIO_LOOKUP_IDX("A", 6, "cs", 0, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("A", 7, "cs", 1, GPIO_ACTIVE_LOW),
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v3 08/11] PCI: layerscape: Modify the MSIX to the doorbell mode
From: Andrew Murray @ 2019-09-02 12:01 UTC (permalink / raw)
To: Xiaowei Bao
Cc: mark.rutland, roy.zang, lorenzo.pieralisi, arnd, devicetree,
jingoohan1, zhiqiang.hou, linuxppc-dev, linux-pci, linux-kernel,
kishon, minghuan.Lian, robh+dt, gregkh, linux-arm-kernel,
gustavo.pimentel, leoyang.li, shawnguo, mingkai.hu
In-Reply-To: <20190902031716.43195-9-xiaowei.bao@nxp.com>
On Mon, Sep 02, 2019 at 11:17:13AM +0800, Xiaowei Bao wrote:
> dw_pcie_ep_raise_msix_irq was never called in the exisitng driver
> before, because the ls1046a platform don't support the MSIX feature
> and msix_capable was always set to false.
> Now that add the ls1088a platform with MSIX support, but the existing
> dw_pcie_ep_raise_msix_irq doesn't work, so use the doorbell method to
> support the MSIX feature.
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
Reviewed-by: Andrew Murray <andrew.murray@arm.com>
> ---
> v2:
> - No change
> v3:
> - Modify the commit message make it clearly.
>
> drivers/pci/controller/dwc/pci-layerscape-ep.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index 1e07287..5f0cb99 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -79,7 +79,8 @@ static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
> case PCI_EPC_IRQ_MSI:
> return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
> case PCI_EPC_IRQ_MSIX:
> - return dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num);
> + return dw_pcie_ep_raise_msix_irq_doorbell(ep, func_no,
> + interrupt_num);
> default:
> dev_err(pci->dev, "UNKNOWN IRQ type\n");
> return -EINVAL;
> --
> 2.9.5
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 4/7] usb: mtk-xhci: support ip-sleep wakeup for MT8183
From: kbuild test robot @ 2019-09-02 11:58 UTC (permalink / raw)
To: Chunfeng Yun
Cc: Mark Rutland, devicetree, Mathias Nyman, Greg Kroah-Hartman,
linux-usb, linux-kernel, Chunfeng Yun, Rob Herring,
linux-mediatek, kbuild-all, Matthias Brugger, linux-arm-kernel
In-Reply-To: <1567150854-30033-5-git-send-email-chunfeng.yun@mediatek.com>
[-- Attachment #1: Type: text/plain, Size: 3555 bytes --]
Hi Chunfeng,
I love your patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[cannot apply to v5.3-rc6 next-20190830]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Chunfeng-Yun/add-support-USB-for-MT8183/20190901-163637
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 7.4.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=ia64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
In file included from include/linux/bitops.h:5:0,
from include/linux/kernel.h:12,
from include/linux/clk.h:13,
from drivers/usb/host/xhci-mtk.c:10:
drivers/usb/host/xhci-mtk.c: In function 'usb_wakeup_ip_sleep_set':
include/linux/bits.h:8:19: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define BIT(nr) (UL(1) << (nr))
^
>> drivers/usb/host/xhci-mtk.c:64:19: note: in expansion of macro 'BIT'
#define WC0_IS_EN BIT(6)
^~~
>> drivers/usb/host/xhci-mtk.c:294:9: note: in expansion of macro 'WC0_IS_EN'
msk = WC0_IS_EN | WC0_IS_C(0xf) | WC0_IS_P;
^~~~~~~~~
vim +/BIT +64 drivers/usb/host/xhci-mtk.c
> 10 #include <linux/clk.h>
11 #include <linux/dma-mapping.h>
12 #include <linux/iopoll.h>
13 #include <linux/kernel.h>
14 #include <linux/mfd/syscon.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/platform_device.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/regmap.h>
20 #include <linux/regulator/consumer.h>
21
22 #include "xhci.h"
23 #include "xhci-mtk.h"
24
25 /* ip_pw_ctrl0 register */
26 #define CTRL0_IP_SW_RST BIT(0)
27
28 /* ip_pw_ctrl1 register */
29 #define CTRL1_IP_HOST_PDN BIT(0)
30
31 /* ip_pw_ctrl2 register */
32 #define CTRL2_IP_DEV_PDN BIT(0)
33
34 /* ip_pw_sts1 register */
35 #define STS1_IP_SLEEP_STS BIT(30)
36 #define STS1_U3_MAC_RST BIT(16)
37 #define STS1_XHCI_RST BIT(11)
38 #define STS1_SYS125_RST BIT(10)
39 #define STS1_REF_RST BIT(8)
40 #define STS1_SYSPLL_STABLE BIT(0)
41
42 /* ip_xhci_cap register */
43 #define CAP_U3_PORT_NUM(p) ((p) & 0xff)
44 #define CAP_U2_PORT_NUM(p) (((p) >> 8) & 0xff)
45
46 /* u3_ctrl_p register */
47 #define CTRL_U3_PORT_HOST_SEL BIT(2)
48 #define CTRL_U3_PORT_PDN BIT(1)
49 #define CTRL_U3_PORT_DIS BIT(0)
50
51 /* u2_ctrl_p register */
52 #define CTRL_U2_PORT_HOST_SEL BIT(2)
53 #define CTRL_U2_PORT_PDN BIT(1)
54 #define CTRL_U2_PORT_DIS BIT(0)
55
56 /* u2_phy_pll register */
57 #define CTRL_U2_FORCE_PLL_STB BIT(28)
58
59 /* usb remote wakeup registers in syscon */
60 /* mt8183 etc */
61 #define PERI_WK_CTRL0 0x20
62 #define WC0_IS_C(x) (((x) & 0xf) << 28) /* cycle debounce */
63 #define WC0_IS_P BIT(12) /* polarity */
> 64 #define WC0_IS_EN BIT(6)
65
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 54621 bytes --]
[-- Attachment #3: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2] drm: dw-hdmi-i2s: enable audio clock in audio_startup
From: Neil Armstrong @ 2019-09-02 11:57 UTC (permalink / raw)
To: Jonas Karlman, Cheng-Yi Chiang, linux-kernel@vger.kernel.org
Cc: alsa-devel@alsa-project.org, tzungbi@chromium.org,
zhengxing@rock-chips.com, kuninori.morimoto.gx@renesas.com,
linux-rockchip@lists.infradead.org, airlied@linux.ie,
jeffy.chen@rock-chips.com, dianders@chromium.org,
dri-devel@lists.freedesktop.org, cain.cai@rock-chips.com,
a.hajda@samsung.com, eddie.cai@rock-chips.com,
Laurent.pinchart@ideasonboard.com, daniel@ffwll.ch,
enric.balletbo@collabora.com, dgreid@chromium.org,
sam@ravnborg.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <HE1PR06MB4011E2F58875F30446D902BFACBE0@HE1PR06MB4011.eurprd06.prod.outlook.com>
On 02/09/2019 12:32, Jonas Karlman wrote:
> On 2019-09-02 11:42, Neil Armstrong wrote:
>> Hi,
>>
>> On 02/09/2019 05:54, Cheng-Yi Chiang wrote:
>>> In the designware databook, the sequence of enabling audio clock and
>>> setting format is not clearly specified.
>>> Currently, audio clock is enabled in the end of hw_param ops after
>>> setting format.
>>>
>>> On some monitors, there is a possibility that audio does not come out.
>>> Fix this by enabling audio clock in audio_startup ops
>>> before hw_param ops setting format.
>>>
>>> Signed-off-by: Cheng-Yi Chiang <cychiang@chromium.org>
>>> Reviewed-by: Douglas Anderson <dianders@chromium.org>
>>> Reviewed-by: Jonas Karlman <jonas@kwiboo.se>
>>> Tested-by: Douglas Anderson <dianders@chromium.org>
>>> ---
>>> Changes from v1:
>>> 1. Move audio_startup to the front of audio_shutdown.
>>> 2. Fix the indentation of audio_startup equal sign using tab.
>>> 3. Rebase the patch on linux-next/master.
>>> 4. Add Reviewed-by and Tested-by fields from dianders@chromium.org.
>>> 5. Add Reviewed-by field from jonas@kwiboo.se.
>>>
>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 9 +++++++++
>>> 1 file changed, 9 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
>>> index 1d15cf9b6821..34d8e837555f 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
>>> @@ -109,6 +109,14 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
>>> hdmi_write(audio, conf0, HDMI_AUD_CONF0);
>>> hdmi_write(audio, conf1, HDMI_AUD_CONF1);
>>>
>>> + return 0;
>>> +}
>>> +
>>> +static int dw_hdmi_i2s_audio_startup(struct device *dev, void *data)
>>> +{
>>> + struct dw_hdmi_i2s_audio_data *audio = data;
>>> + struct dw_hdmi *hdmi = audio->hdmi;
>>> +
>>> dw_hdmi_audio_enable(hdmi);
>>>
>>> return 0;
>>> @@ -153,6 +161,7 @@ static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
>>>
>>> static struct hdmi_codec_ops dw_hdmi_i2s_ops = {
>>> .hw_params = dw_hdmi_i2s_hw_params,
>>> + .audio_startup = dw_hdmi_i2s_audio_startup,
>>> .audio_shutdown = dw_hdmi_i2s_audio_shutdown,
>>> .get_eld = dw_hdmi_i2s_get_eld,
>>> .get_dai_id = dw_hdmi_i2s_get_dai_id,
>>>
>> Looks sane, Jonas should I apply it now it's rebased ?
>
> Sure, looks sane and compiles without warnings on my build host.
Thx, Applied to drm-misc-next
Neil
>
> Regards,
> Jonas
>
>>
>> Neil
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC PATCH V2 4/4] platform: mtk-isp: Add Mediatek FD driver
From: Jerry-ch Chen @ 2019-09-02 11:47 UTC (permalink / raw)
To: Tomasz Figa
Cc: devicetree@vger.kernel.org, Sean Cheng (鄭昇弘),
laurent.pinchart+renesas@ideasonboard.com,
Rynn Wu (吳育恩), srv_heupstream,
Po-Yang Huang (黃柏陽), mchehab@kernel.org,
suleiman@chromium.org, shik@chromium.org,
Jungo Lin (林明俊),
Sj Huang (黃信璋), yuzhao@chromium.org,
linux-mediatek@lists.infradead.org, zwisler@chromium.org,
matthias.bgg@gmail.com, Christie Yu (游雅惠),
Frederic Chen (陳俊元), hans.verkuil@cisco.com,
linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org
In-Reply-To: <CAAFQd5D-Yg1FjUE_rwmqfS1gvfE0=MZ=r-ziueU_37-uo9QTbw@mail.gmail.com>
Hi Tomasz,
On Fri, 2019-08-30 at 16:33 +0800, Tomasz Figa wrote:
> On Wed, Aug 28, 2019 at 11:00 AM Jerry-ch Chen
> <Jerry-ch.Chen@mediatek.com> wrote:
> >
> > Hi Tomasz,
> >
> > On Mon, 2019-08-26 at 14:36 +0800, Tomasz Figa wrote:
> > > Hi Jerry,
> > >
> > > On Sun, Aug 25, 2019 at 6:18 PM Jerry-ch Chen
> > > <Jerry-ch.Chen@mediatek.com> wrote:
> > > >
> > > > Hi Tomasz,
> > > >
> > > > On Fri, 2019-08-02 at 16:28 +0800, Tomasz Figa wrote:
> > > > > Hi Jerry,
> > > > >
> > > > > On Tue, Jul 09, 2019 at 04:41:12PM +0800, Jerry-ch Chen wrote:
> > > > > > From: Jerry-ch Chen <jerry-ch.chen@mediatek.com>
> > > > > >
> > > > > > This patch adds the driver of Face Detection (FD) unit in
> > > > > > Mediatek camera system, providing face detection function.
> > > > > >
> > > > > > The mtk-isp directory will contain drivers for multiple IP
> > > > > > blocks found in Mediatek ISP system. It will include ISP Pass 1
> > > > > > driver (CAM), sensor interface driver, DIP driver and face
> > > > > > detection driver.
> > > > > >
> > > > > > Signed-off-by: Jerry-ch Chen <jerry-ch.chen@mediatek.com>
> > > > > > ---
> > > > > > drivers/media/platform/Makefile | 2 +
> > > > > > drivers/media/platform/mtk-isp/fd/Makefile | 5 +
> > > > > > drivers/media/platform/mtk-isp/fd/mtk_fd.h | 157 +++
> > > > > > drivers/media/platform/mtk-isp/fd/mtk_fd_40.c | 1259 +++++++++++++++++++++++++
> > > > > > include/uapi/linux/v4l2-controls.h | 4 +
> > > > > > 5 files changed, 1427 insertions(+)
> > > > > > create mode 100644 drivers/media/platform/mtk-isp/fd/Makefile
> > > > > > create mode 100644 drivers/media/platform/mtk-isp/fd/mtk_fd.h
> > > > > > create mode 100644 drivers/media/platform/mtk-isp/fd/mtk_fd_40.c
> > > > > >
> > > > >
> > > > > Thanks for the patch! I finally got a chance to fully review the code. Sorry
> > > > > for the delay. Please check my comments inline.
> > > > >
> > > > I appreciate your comments.
> > > > I've fixed most of the comments and verifying them,
> > > > Sorry for the delay, here is the reply.
> > > >
> > >
> > > Thanks for replying to all the comments, it's very helpful. I'll snip
> > > the parts that I don't have any further comments.
> > >
> > > [snip]
> > >
> > > > > > + if (usercount == 1) {
> > > > > > + pm_runtime_get_sync(&fd_dev->pdev->dev);
> > > > > > + if (mtk_fd_hw_enable(fd_hw)) {
> > > > > > + pm_runtime_put_sync(&fd_dev->pdev->dev);
> > > > > > + atomic_dec_return(&fd_hw->fd_user_cnt);
> > > > > > + mutex_unlock(&fd_hw->fd_hw_lock);
> > > > > > + return -EINVAL;
> > > > > > + }
> > > > > > + }
> > > > >
> > > > > This is a simple mem-to-mem device, so there is no reason to keep it active
> > > > > all the time it's streaming. Please just get the runtime PM counter when
> > > > > queuing a job to the hardware and release it when the job finishes.
> > > > >
> > > > > I guess we might still want to do the costly operations like rproc_boot()
> > > > > when we start streaming, though.
> > > > >
> > > > Do you mean by moving the pm_runtime_get/put stuff to the job execution
> > > > and job finish place?
> > >
> > > Yes.
> > >
> > > > the rproc_boot() operation will be done here.
> > > >
> > >
> > > How much time does the rproc_boot() operation take?
> > >
> >
> > About 0.7~1.3ms, average 0.8ms (14 measurements)
> >
>
> Okay, I think we may want to call it when we start streaming then.
>
Done.
> [snip]
>
> > > > > > +static int mtk_fd_vb2_queue_setup(struct vb2_queue *vq,
> > > > > > + unsigned int *num_buffers,
> > > > > > + unsigned int *num_planes,
> > > > > > + unsigned int sizes[],
> > > > > > + struct device *alloc_devs[])
> > > > > > +{
> > > > > > + struct mtk_fd_ctx *ctx = vb2_get_drv_priv(vq);
> > > > > > + struct device *dev = ctx->dev;
> > > > > > + unsigned int size;
> > > > > > +
> > > > > > + switch (vq->type) {
> > > > > > + case V4L2_BUF_TYPE_META_CAPTURE:
> > > > > > + size = ctx->dst_fmt.buffersize;
> > > > > > + break;
> > > > > > + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
> > > > > > + size = ctx->src_fmt.plane_fmt[0].sizeimage;
> > > > > > + break;
> > > > > > + default:
> > > > > > + dev_err(dev, "invalid queue type: %d\n", vq->type);
> > > > >
> > > > > We should need to handle this.
> > > > >
> > > > Do you mean by giving a size instead of return -EINVAL?
> > > >
> > >
> > > Sorry, typo. I meant we shouldn't need to handle it, because we can't
> > > get any other queue type here.
> > >
> >
> > Ok, I see, I will remove it.
> > also, this function will be updated as following due to the 2 plane
> > case.
> >
> > static int mtk_fd_vb2_queue_setup(struct vb2_queue *vq,
> > unsigned int *num_buffers,
> > unsigned int *num_planes,
> > unsigned int sizes[],
> > struct device *alloc_devs[])
> > {
> > struct mtk_fd_ctx *ctx = vb2_get_drv_priv(vq);
> > struct device *dev = ctx->dev;
> > unsigned int size[2];
> >
> > switch (vq->type) {
> > case V4L2_BUF_TYPE_META_CAPTURE:
> > size[0] = ctx->dst_fmt.buffersize;
> > break;
> > case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
> > size[0] = ctx->src_fmt.plane_fmt[0].sizeimage;
> > if (*num_planes == 2)
> > size[1] = ctx->src_fmt.plane_fmt[1].sizeimage;
> > break;
> > }
> >
> > if (*num_planes == 1) {
> > if (sizes[0] < size[0])
> > return -EINVAL;
> > } else if (*num_planes == 2) {
> > if ((sizes[0] < size[0]) && (sizes[1] < size[1]))
> > return -EINVAL;
>
> Can we just use a loop here and combine the 2 cases above?
>
> Also, we need to fail with -EINVAL if *num_planes is > 2.
>
> > } else {
> > *num_planes = 1;
> > sizes[0] = size[0];
>
> This should be the case if *num_planes == 0 and the number of planes
> and sizes should match the currently active format.
>
I appreciate your comments,
Ok, I will update as following:
static int mtk_fd_vb2_queue_setup(struct vb2_queue *vq,
unsigned int *num_buffers,
unsigned int *num_planes,
unsigned int sizes[],
struct device *alloc_devs[])
{
struct mtk_fd_ctx *ctx = vb2_get_drv_priv(vq);
unsigned int size[2];
unsigned int plane;
switch (vq->type) {
case V4L2_BUF_TYPE_META_CAPTURE:
size[0] = ctx->dst_fmt.buffersize;
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
size[0] = ctx->src_fmt.plane_fmt[0].sizeimage;
if (*num_planes == 2)
size[1] = ctx->src_fmt.plane_fmt[1].sizeimage;
break;
}
if (*num_planes > 2)
return -EINVAL;
if (*num_planes == 0) {
if (vq->type == V4L2_BUF_TYPE_META_CAPTURE) {
sizes[0] = ctx->dst_fmt.buffersize;
*num_planes = 1;
return 0;
}
*num_planes = ctx->src_fmt.num_planes;
for (plane = 0; plane < *num_planes; plane++)
sizes[plane] = ctx->src_fmt.plane_fmt[plane].sizeimage;
return 0;
}
for (plane = 0; plane < *num_planes; plane++) {
if(sizes[plane] < size[plane])
return -EINVAL;
}
return 0;
}
> > }
> >
> > return 0;
> > }
> >
> > > [snip]
> > >
> > > > > > +static void mtk_fd_vb2_stop_streaming(struct vb2_queue *vq)
> > > > > > +{
> > > > > > + struct mtk_fd_ctx *ctx = vb2_get_drv_priv(vq);
> > > > > > + struct vb2_buffer *vb;
> > > > >
> > > > > How do we guarantee here that the hardware isn't still accessing the buffers
> > > > > removed below?
> > > > >
> > > > Maybe we can check the driver state flag and aborting the unfinished
> > > > jobs?
> > > > (fd_hw->state == FD_ENQ)
> > > >
> > >
> > > Yes, we need to either cancel or wait for the currently processing
> > > job. It depends on hardware capabilities, but cancelling is generally
> > > preferred for the lower latency.
> > >
> > Ok, it the state is ENQ, then we can disable the FD hw by controlling
> > the registers.
> >
> > for example:
> > writel(0x0, fd->fd_base + FD_HW_ENABLE);
> > writel(0x0, fd->fd_base + FD_INT_EN);
> >
>
> What's exactly the effect of writing 0 to FD_HW_ENABLE?
>
Sorry, my last reply didn't solve the question,
we should implement a mtk_fd_job_abort() for v4l2_m2m_ops().
which is able to readl_poll_timeout_atomic()
and check the HW busy bits in the register FD_INT_EN;
if they are not cleared until timeout, we could handle the last
processing job.
Otherwise, the FD irq handler should have handled the last processing
job and we could continue the stop_streaming().
For job_abort():
static void mtk_fd_job_abort(void *priv)
{
struct mtk_fd_ctx *ctx = priv;
struct mtk_fd_dev *fd = ctx->fd_dev;
u32 val;
u32 ret;
ret = readl_poll_timeout_atomic(fd->fd_base + MTK_FD_REG_OFFSET_INT_EN,
val,
(val & MTK_FD_HW_BUSY_MASK) ==
MTK_FD_HW_STATE_IS_BUSY,
USEC_PER_MSEC, MTK_FD_STOP_HW_TIMEOUT);
if (ret) {
dev_warn(fd->dev, "FD HW timeout\n");
mtk_fd_hw_job_finish(fd, VB2_BUF_STATE_ERROR);
}
writel(0x0, fd->fd_base + MTK_FD_REG_OFFSET_HW_ENABLE);
writel(0x0, fd->fd_base + MTK_FD_REG_OFFSET_INT_EN);
}
Best Regards,
Jerry
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH RESEND v2 1/6] dt-bindings: watchdog: Add YAML schemas for the generic watchdog bindings
From: Maxime Ripard @ 2019-09-02 11:46 UTC (permalink / raw)
To: Guenter Roeck
Cc: Mark Rutland, devicetree, linux-watchdog, linux-kernel,
Chen-Yu Tsai, Rob Herring, wim, Frank Rowand, linux-arm-kernel
In-Reply-To: <20190830164811.GA7911@roeck-us.net>
Hi Guenther,
On Fri, Aug 30, 2019 at 09:48:11AM -0700, Guenter Roeck wrote:
> On Wed, Aug 21, 2019 at 04:38:30PM +0200, Maxime Ripard wrote:
> > From: Maxime Ripard <maxime.ripard@bootlin.com>
> >
> > The watchdogs have a bunch of generic properties that are needed in a
> > device tree. Add a YAML schemas for those.
> >
> > Reviewed-by: Rob Herring <robh@kernel.org>
> > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
>
> Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Thanks for reviewing this, which tree should this go through? Yours or Rob's?
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V3 4/6] PCI: tegra: Add support to enable slot regulators
From: Thierry Reding @ 2019-09-02 11:40 UTC (permalink / raw)
To: Vidya Sagar
Cc: devicetree, lorenzo.pieralisi, mperttunen, mmaddireddy, kthota,
gustavo.pimentel, linux-kernel, kishon, linux-tegra, robh+dt,
linux-pci, bhelgaas, andrew.murray, digetx, jonathanh,
linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-5-vidyas@nvidia.com>
[-- Attachment #1.1: Type: text/plain, Size: 968 bytes --]
On Wed, Aug 28, 2019 at 10:58:48PM +0530, Vidya Sagar wrote:
> Add support to get regulator information of 3.3V and 12V supplies of a PCIe
> slot from the respective controller's device-tree node and enable those
> supplies. This is required in platforms like p2972-0000 where the supplies
> to x16 slot owned by C5 controller need to be enabled before attempting to
> enumerate the devices.
>
> Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
> ---
> V3:
> * Added a dev_err() print for failure case of tegra_pcie_get_slot_regulators() API
> * Modified to make 100ms sleep valid only if at least one of the regulator handles exist
>
> V2:
> * Addressed review comments from Thierry Reding and Andrew Murray
> * Handled failure case of devm_regulator_get_optional() for -ENODEV cleanly
>
> drivers/pci/controller/dwc/pcie-tegra194.c | 83 ++++++++++++++++++++++
> 1 file changed, 83 insertions(+)
Acked-by: Thierry Reding <treding@nvidia.com>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V3 3/6] PCI: tegra: Add support to configure sideband pins
From: Thierry Reding @ 2019-09-02 11:38 UTC (permalink / raw)
To: Vidya Sagar
Cc: devicetree, lorenzo.pieralisi, mperttunen, mmaddireddy, kthota,
gustavo.pimentel, linux-kernel, kishon, linux-tegra, robh+dt,
linux-pci, bhelgaas, andrew.murray, digetx, jonathanh,
linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-4-vidyas@nvidia.com>
[-- Attachment #1.1: Type: text/plain, Size: 594 bytes --]
On Wed, Aug 28, 2019 at 10:58:47PM +0530, Vidya Sagar wrote:
> Add support to configure sideband signal pins when information is present
> in respective controller's device-tree node.
>
> Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
> ---
> V3:
> * Used 'dev' instead of 'pcie->dev'
>
> V2:
> * Addressed review comment from Andrew Murray
> * Handled failure case of pinctrl_pm_select_default_state() cleanly
>
> drivers/pci/controller/dwc/pcie-tegra194.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
Acked-by: Thierry Reding <treding@nvidia.com>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox