All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] 8250: AMD Carrizo UART PL300 DMA enablement
@ 2015-12-04  3:24 ` Wang Hongcheng
  0 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

Hi all,

As AMD carrizo UART device is compatible with 8250 and has pl330 DMA
IP, our uart driver is serial:8250 and DMA engines are registered by
driver/dma/pl330. The following patches are made, in order to enable
DMA.

Firstly, we add an universal ACPI amba glue layer to create an amba
device based on ACPI table. Then we alter 8250/Kconfig to support
AMD 8250 device and add quirk for AMD specific request.
Secondly, since pl330 driver only provides dma engine for platform
devices, we add an acpi dma engine interface.
Then we add a new port type for AMD carrizo and set UART registers
and dma rx size as hardware requirement.
In the end, we make our IOMMU driver to support non-pci device, so
UART DMA really works.

Thanks,
Hongcheng

Huang Rui (1):
  ACPI: Add support for AMBA bus type

Wan Zongshun (2):
  Documentation: Add ivrs_acpihid kernel parameter description
  iommu/amd: Add ACPI HID named devices IOMMU driver support

Wang Hongcheng (6):
  8250/Kconfig: add config option CONFIG_SERIAL_8250_AMD
  ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config
  dmaengine: pl330: add new items for pl330 private data
  dmaengine: pl330: provide ACPI dmaengine interface
  dmaengine:pl330: set segment_boundary_mask = 0cffffffff
  Serial:8250: New Port Type PORT_AMD_8250

 Documentation/kernel-parameters.txt |   7 ++
 drivers/acpi/Makefile               |   1 +
 drivers/acpi/acpi_amba.c            | 180 ++++++++++++++++++++++++++++++++++++
 drivers/acpi/acpi_apd.c             |  89 +++++++++++++++---
 drivers/dma/pl330.c                 |  61 ++++++++++--
 drivers/iommu/amd_iommu.c           | 165 +++++++++++++++++++++++++++++----
 drivers/iommu/amd_iommu_init.c      | 123 +++++++++++++++++++++++-
 drivers/iommu/amd_iommu_types.h     |  11 +++
 drivers/tty/serial/8250/8250_dw.c   |  16 ++++
 drivers/tty/serial/8250/8250_port.c |   9 ++
 drivers/tty/serial/8250/Kconfig     |   8 ++
 include/linux/acpi.h                |  30 ++++++
 include/linux/amba/pl330.h          |   4 +
 include/linux/serial_8250.h         |   4 +
 include/uapi/linux/serial_core.h    |   3 +-
 include/uapi/linux/serial_reg.h     |   2 +
 16 files changed, 673 insertions(+), 40 deletions(-)
 create mode 100644 drivers/acpi/acpi_amba.c

-- 
1.9.1

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

* [PATCH 0/9] 8250: AMD Carrizo UART PL300 DMA enablement
@ 2015-12-04  3:24 ` Wang Hongcheng
  0 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

Hi all,

As AMD carrizo UART device is compatible with 8250 and has pl330 DMA
IP, our uart driver is serial:8250 and DMA engines are registered by
driver/dma/pl330. The following patches are made, in order to enable
DMA.

Firstly, we add an universal ACPI amba glue layer to create an amba
device based on ACPI table. Then we alter 8250/Kconfig to support
AMD 8250 device and add quirk for AMD specific request.
Secondly, since pl330 driver only provides dma engine for platform
devices, we add an acpi dma engine interface.
Then we add a new port type for AMD carrizo and set UART registers
and dma rx size as hardware requirement.
In the end, we make our IOMMU driver to support non-pci device, so
UART DMA really works.

Thanks,
Hongcheng

Huang Rui (1):
  ACPI: Add support for AMBA bus type

Wan Zongshun (2):
  Documentation: Add ivrs_acpihid kernel parameter description
  iommu/amd: Add ACPI HID named devices IOMMU driver support

Wang Hongcheng (6):
  8250/Kconfig: add config option CONFIG_SERIAL_8250_AMD
  ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config
  dmaengine: pl330: add new items for pl330 private data
  dmaengine: pl330: provide ACPI dmaengine interface
  dmaengine:pl330: set segment_boundary_mask = 0cffffffff
  Serial:8250: New Port Type PORT_AMD_8250

 Documentation/kernel-parameters.txt |   7 ++
 drivers/acpi/Makefile               |   1 +
 drivers/acpi/acpi_amba.c            | 180 ++++++++++++++++++++++++++++++++++++
 drivers/acpi/acpi_apd.c             |  89 +++++++++++++++---
 drivers/dma/pl330.c                 |  61 ++++++++++--
 drivers/iommu/amd_iommu.c           | 165 +++++++++++++++++++++++++++++----
 drivers/iommu/amd_iommu_init.c      | 123 +++++++++++++++++++++++-
 drivers/iommu/amd_iommu_types.h     |  11 +++
 drivers/tty/serial/8250/8250_dw.c   |  16 ++++
 drivers/tty/serial/8250/8250_port.c |   9 ++
 drivers/tty/serial/8250/Kconfig     |   8 ++
 include/linux/acpi.h                |  30 ++++++
 include/linux/amba/pl330.h          |   4 +
 include/linux/serial_8250.h         |   4 +
 include/uapi/linux/serial_core.h    |   3 +-
 include/uapi/linux/serial_reg.h     |   2 +
 16 files changed, 673 insertions(+), 40 deletions(-)
 create mode 100644 drivers/acpi/acpi_amba.c

-- 
1.9.1


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

* [PATCH 1/9] ACPI: Add support for AMBA bus type
  2015-12-04  3:24 ` Wang Hongcheng
@ 2015-12-04  3:24   ` Wang Hongcheng
  -1 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

From: Huang Rui <ray.huang@amd.com>

Inspired by acpi platform bus type, to make driver "porting" more
straightforward, this patch introduces ACPI support to the AMBA bus
type. Instead of writing ACPI "glue" drivers for the exiting AMBA
drivers.

In the subsequent patches, we will use this function to support pl330
AMBA driver.

Signed-off-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/acpi/Makefile    |   1 +
 drivers/acpi/acpi_amba.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h     |  21 +++++++
 3 files changed, 179 insertions(+)
 create mode 100644 drivers/acpi/acpi_amba.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 675eaf3..7d84446 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -42,6 +42,7 @@ acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
 acpi-y				+= pci_root.o pci_link.o pci_irq.o
 acpi-y				+= acpi_lpss.o acpi_apd.o
 acpi-y				+= acpi_platform.o
+acpi-$(CONFIG_ARM_AMBA)		+= acpi_amba.o
 acpi-y				+= acpi_pnp.o
 acpi-y				+= int340x_thermal.o
 acpi-y				+= power.o
diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
new file mode 100644
index 0000000..4f0366a
--- /dev/null
+++ b/drivers/acpi/acpi_amba.c
@@ -0,0 +1,157 @@
+/*
+ * ACPI support for AMBA bus type.
+ *
+ * Copyright (C) 2015, Advanced Micro Devices, Inc.
+ * Authors: Huang Rui <ray.huang@amd.com>
+ *          Wang Hongcheng <annie.wang@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/amba/bus.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+
+#include "internal.h"
+
+ACPI_MODULE_NAME("amba");
+
+/**
+ * acpi_create_amba_device - Create AMBA device for ACPI device node.
+ * @adev: ACPI device node to create an AMBA device.
+ * @periphid: AMBA device periphid.
+ * @fixed_rate: Clock frequency.
+ * @pdata: Platform data specific to the device.
+ *
+ * Check if the given @adev can be represented as an AMBA device and, if
+ * that's the case, create and register an AMBA device, populate its
+ * common resources and returns a pointer to it.  Otherwise, return
+ * %NULL or ERR_PTR() on error.
+ *
+ * Name of the AMBA device will be the same as @adev's.
+ */
+struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
+					    unsigned int periphid,
+					    unsigned long fixed_rate,
+					    void *pdata)
+{
+	struct amba_device *amba_dev = NULL;
+	struct device *parent;
+	struct acpi_device *acpi_parent;
+	struct resource_entry *rentry;
+	struct list_head resource_list;
+	struct resource *resource = NULL;
+	int count, ret = 0;
+	unsigned int i;
+	unsigned int irq[AMBA_NR_IRQS];
+	struct clk *clk = ERR_PTR(-ENODEV);
+
+	/*
+	 * If the ACPI node already has a physical device attached,
+	 * skip it.
+	 */
+	if (adev->physical_node_count)
+		return NULL;
+
+	INIT_LIST_HEAD(&resource_list);
+	count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
+	if (count <= 0)
+		return NULL;
+
+	resource = kzalloc(sizeof(*resource), GFP_KERNEL);
+	if (!resource)
+		goto resource_alloc_err;
+
+	count = 0;
+	list_for_each_entry(rentry, &resource_list, node) {
+		if (resource_type(rentry->res) == IORESOURCE_IRQ) {
+			irq[count] = rentry->res->start;
+			count++;
+		}
+		/*
+		 * there is only one io memory resource entry
+		 * at current AMBA device design
+		 */
+		if (resource_type(rentry->res) | IORESOURCE_MEM)
+			memcpy(resource, rentry->res, sizeof(struct resource));
+	}
+
+	amba_dev = amba_device_alloc(dev_name(&adev->dev),
+				     resource->start,
+				     resource_size(resource));
+
+	if (!amba_dev)
+		goto amba_alloc_err;
+
+	amba_dev->dev.coherent_dma_mask = acpi_dma_supported(adev) ? DMA_BIT_MASK(64) : 0;
+	amba_dev->dev.platform_data = pdata;
+	amba_dev->dev.fwnode = acpi_fwnode_handle(adev);
+
+	/*
+	 * If the ACPI node has a parent and that parent has a
+	 * physical device attached to it, that physical device should
+	 * be the parent of the AMBA device we are about to create.
+	 */
+	parent = NULL;
+	acpi_parent = adev->parent;
+	if (acpi_parent) {
+		struct acpi_device_physical_node *entry;
+		struct list_head *list;
+
+		mutex_lock(&acpi_parent->physical_node_lock);
+		list = &acpi_parent->physical_node_list;
+		if (!list_empty(list)) {
+			entry = list_first_entry(list, struct acpi_device_physical_node, node);
+			parent = entry->dev;
+		}
+		mutex_unlock(&acpi_parent->physical_node_lock);
+	}
+
+	amba_dev->dev.parent = parent;
+	amba_dev->periphid = periphid;
+
+	WARN_ON_ONCE(count > AMBA_NR_IRQS);
+
+	for (i = 0; i < count; i++)
+		amba_dev->irq[i] = irq[i];
+
+	clk = clk_register_fixed_rate(&amba_dev->dev,
+				      dev_name(&amba_dev->dev),
+				      NULL, CLK_IS_ROOT,
+				      fixed_rate);
+	if (IS_ERR_OR_NULL(clk))
+		goto amba_register_err;
+
+	ret = clk_register_clkdev(clk, "apb_pclk",
+				  dev_name(&amba_dev->dev));
+	if (ret)
+		goto amba_register_err;
+
+	ret = amba_device_add(amba_dev, resource);
+	if (ret)
+		goto amba_register_err;
+
+	acpi_dev_free_resource_list(&resource_list);
+	kfree(resource);
+	return amba_dev;
+
+amba_register_err:
+	amba_device_put(amba_dev);
+
+amba_alloc_err:
+	kfree(resource);
+
+resource_alloc_err:
+	acpi_dev_free_resource_list(&resource_list);
+
+	return ERR_PTR(ret);
+}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 0548339..04827d8 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -37,6 +37,7 @@
 #include <linux/list.h>
 #include <linux/mod_devicetable.h>
 #include <linux/dynamic_debug.h>
+#include <linux/amba/bus.h>
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -466,6 +467,26 @@ int acpi_device_modalias(struct device *, char *, int);
 void acpi_walk_dep_device_list(acpi_handle handle);
 
 struct platform_device *acpi_create_platform_device(struct acpi_device *);
+
+#ifdef CONFIG_ARM_AMBA
+
+struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
+					    unsigned int periphid,
+					    unsigned long fixed_rate,
+					    void *pdata);
+
+#else /* !CONFIG_ARM_AMBA */
+
+static inline struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
+							  unsigned int periphid,
+							  unsigned long fixed_rate,
+							  void *pdata)
+{
+	return NULL;
+}
+
+#endif
+
 #define ACPI_PTR(_ptr)	(_ptr)
 
 #else	/* !CONFIG_ACPI */
-- 
1.9.1


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

* [PATCH 1/9] ACPI: Add support for AMBA bus type
@ 2015-12-04  3:24   ` Wang Hongcheng
  0 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

From: Huang Rui <ray.huang@amd.com>

Inspired by acpi platform bus type, to make driver "porting" more
straightforward, this patch introduces ACPI support to the AMBA bus
type. Instead of writing ACPI "glue" drivers for the exiting AMBA
drivers.

In the subsequent patches, we will use this function to support pl330
AMBA driver.

Signed-off-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/acpi/Makefile    |   1 +
 drivers/acpi/acpi_amba.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h     |  21 +++++++
 3 files changed, 179 insertions(+)
 create mode 100644 drivers/acpi/acpi_amba.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 675eaf3..7d84446 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -42,6 +42,7 @@ acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
 acpi-y				+= pci_root.o pci_link.o pci_irq.o
 acpi-y				+= acpi_lpss.o acpi_apd.o
 acpi-y				+= acpi_platform.o
+acpi-$(CONFIG_ARM_AMBA)		+= acpi_amba.o
 acpi-y				+= acpi_pnp.o
 acpi-y				+= int340x_thermal.o
 acpi-y				+= power.o
diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
new file mode 100644
index 0000000..4f0366a
--- /dev/null
+++ b/drivers/acpi/acpi_amba.c
@@ -0,0 +1,157 @@
+/*
+ * ACPI support for AMBA bus type.
+ *
+ * Copyright (C) 2015, Advanced Micro Devices, Inc.
+ * Authors: Huang Rui <ray.huang@amd.com>
+ *          Wang Hongcheng <annie.wang@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/amba/bus.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+
+#include "internal.h"
+
+ACPI_MODULE_NAME("amba");
+
+/**
+ * acpi_create_amba_device - Create AMBA device for ACPI device node.
+ * @adev: ACPI device node to create an AMBA device.
+ * @periphid: AMBA device periphid.
+ * @fixed_rate: Clock frequency.
+ * @pdata: Platform data specific to the device.
+ *
+ * Check if the given @adev can be represented as an AMBA device and, if
+ * that's the case, create and register an AMBA device, populate its
+ * common resources and returns a pointer to it.  Otherwise, return
+ * %NULL or ERR_PTR() on error.
+ *
+ * Name of the AMBA device will be the same as @adev's.
+ */
+struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
+					    unsigned int periphid,
+					    unsigned long fixed_rate,
+					    void *pdata)
+{
+	struct amba_device *amba_dev = NULL;
+	struct device *parent;
+	struct acpi_device *acpi_parent;
+	struct resource_entry *rentry;
+	struct list_head resource_list;
+	struct resource *resource = NULL;
+	int count, ret = 0;
+	unsigned int i;
+	unsigned int irq[AMBA_NR_IRQS];
+	struct clk *clk = ERR_PTR(-ENODEV);
+
+	/*
+	 * If the ACPI node already has a physical device attached,
+	 * skip it.
+	 */
+	if (adev->physical_node_count)
+		return NULL;
+
+	INIT_LIST_HEAD(&resource_list);
+	count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
+	if (count <= 0)
+		return NULL;
+
+	resource = kzalloc(sizeof(*resource), GFP_KERNEL);
+	if (!resource)
+		goto resource_alloc_err;
+
+	count = 0;
+	list_for_each_entry(rentry, &resource_list, node) {
+		if (resource_type(rentry->res) == IORESOURCE_IRQ) {
+			irq[count] = rentry->res->start;
+			count++;
+		}
+		/*
+		 * there is only one io memory resource entry
+		 * at current AMBA device design
+		 */
+		if (resource_type(rentry->res) | IORESOURCE_MEM)
+			memcpy(resource, rentry->res, sizeof(struct resource));
+	}
+
+	amba_dev = amba_device_alloc(dev_name(&adev->dev),
+				     resource->start,
+				     resource_size(resource));
+
+	if (!amba_dev)
+		goto amba_alloc_err;
+
+	amba_dev->dev.coherent_dma_mask = acpi_dma_supported(adev) ? DMA_BIT_MASK(64) : 0;
+	amba_dev->dev.platform_data = pdata;
+	amba_dev->dev.fwnode = acpi_fwnode_handle(adev);
+
+	/*
+	 * If the ACPI node has a parent and that parent has a
+	 * physical device attached to it, that physical device should
+	 * be the parent of the AMBA device we are about to create.
+	 */
+	parent = NULL;
+	acpi_parent = adev->parent;
+	if (acpi_parent) {
+		struct acpi_device_physical_node *entry;
+		struct list_head *list;
+
+		mutex_lock(&acpi_parent->physical_node_lock);
+		list = &acpi_parent->physical_node_list;
+		if (!list_empty(list)) {
+			entry = list_first_entry(list, struct acpi_device_physical_node, node);
+			parent = entry->dev;
+		}
+		mutex_unlock(&acpi_parent->physical_node_lock);
+	}
+
+	amba_dev->dev.parent = parent;
+	amba_dev->periphid = periphid;
+
+	WARN_ON_ONCE(count > AMBA_NR_IRQS);
+
+	for (i = 0; i < count; i++)
+		amba_dev->irq[i] = irq[i];
+
+	clk = clk_register_fixed_rate(&amba_dev->dev,
+				      dev_name(&amba_dev->dev),
+				      NULL, CLK_IS_ROOT,
+				      fixed_rate);
+	if (IS_ERR_OR_NULL(clk))
+		goto amba_register_err;
+
+	ret = clk_register_clkdev(clk, "apb_pclk",
+				  dev_name(&amba_dev->dev));
+	if (ret)
+		goto amba_register_err;
+
+	ret = amba_device_add(amba_dev, resource);
+	if (ret)
+		goto amba_register_err;
+
+	acpi_dev_free_resource_list(&resource_list);
+	kfree(resource);
+	return amba_dev;
+
+amba_register_err:
+	amba_device_put(amba_dev);
+
+amba_alloc_err:
+	kfree(resource);
+
+resource_alloc_err:
+	acpi_dev_free_resource_list(&resource_list);
+
+	return ERR_PTR(ret);
+}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 0548339..04827d8 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -37,6 +37,7 @@
 #include <linux/list.h>
 #include <linux/mod_devicetable.h>
 #include <linux/dynamic_debug.h>
+#include <linux/amba/bus.h>
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -466,6 +467,26 @@ int acpi_device_modalias(struct device *, char *, int);
 void acpi_walk_dep_device_list(acpi_handle handle);
 
 struct platform_device *acpi_create_platform_device(struct acpi_device *);
+
+#ifdef CONFIG_ARM_AMBA
+
+struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
+					    unsigned int periphid,
+					    unsigned long fixed_rate,
+					    void *pdata);
+
+#else /* !CONFIG_ARM_AMBA */
+
+static inline struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
+							  unsigned int periphid,
+							  unsigned long fixed_rate,
+							  void *pdata)
+{
+	return NULL;
+}
+
+#endif
+
 #define ACPI_PTR(_ptr)	(_ptr)
 
 #else	/* !CONFIG_ACPI */
-- 
1.9.1


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

* [PATCH 2/9] 8250/Kconfig: add config option CONFIG_SERIAL_8250_AMD
  2015-12-04  3:24 ` Wang Hongcheng
@ 2015-12-04  3:24   ` Wang Hongcheng
  -1 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

Add config option  CONFIG_SERIAL_8250_AMD in use of AMD carrizo.
Because carrizo's UART DMA device is an amba device, it selects
ARM_AMBA option. Anything uses amba devices must select ARM_AMBA.

Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/tty/serial/8250/Kconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 6412f14..d9717c1 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -378,3 +378,11 @@ config SERIAL_8250_MID
 	  Selecting this option will enable handling of the extra features
 	  present on the UART found on Intel Medfield SOC and various other
 	  Intel platforms.
+
+config SERIAL_8250_AMD
+        bool "AMD carrizo serial port support"
+        depends on SERIAL_8250
+	select ARM_AMBA
+        help
+           If you have a Carrizo  based board and want to use the
+           serial port, say Y to this option. If unsure, say N.
-- 
1.9.1


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

* [PATCH 2/9] 8250/Kconfig: add config option CONFIG_SERIAL_8250_AMD
@ 2015-12-04  3:24   ` Wang Hongcheng
  0 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

Add config option  CONFIG_SERIAL_8250_AMD in use of AMD carrizo.
Because carrizo's UART DMA device is an amba device, it selects
ARM_AMBA option. Anything uses amba devices must select ARM_AMBA.

Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/tty/serial/8250/Kconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 6412f14..d9717c1 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -378,3 +378,11 @@ config SERIAL_8250_MID
 	  Selecting this option will enable handling of the extra features
 	  present on the UART found on Intel Medfield SOC and various other
 	  Intel platforms.
+
+config SERIAL_8250_AMD
+        bool "AMD carrizo serial port support"
+        depends on SERIAL_8250
+	select ARM_AMBA
+        help
+           If you have a Carrizo  based board and want to use the
+           serial port, say Y to this option. If unsure, say N.
-- 
1.9.1


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

* [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config
  2015-12-04  3:24 ` Wang Hongcheng
@ 2015-12-04  3:24   ` Wang Hongcheng
  -1 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

AMD pl330 is a UART DMA device, it shares one ACPI item with UART. So
a platform device and an acpi device will be created according to
AMD0020 ACPI dev. And its mem base address must have an offset. As a
result, MULTI_ATTACHED_QUIRK and MULTI_ATTACHED_QUIRK are used.

Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/acpi/acpi_amba.c | 31 +++++++++++++++++++++++----
 drivers/acpi/acpi_apd.c  | 56 +++++++++++++++++++++++++++++++++++++-----------
 include/linux/acpi.h     | 13 +++++++++--
 3 files changed, 81 insertions(+), 19 deletions(-)

diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
index 4f0366a..8a5269c 100644
--- a/drivers/acpi/acpi_amba.c
+++ b/drivers/acpi/acpi_amba.c
@@ -31,6 +31,8 @@ ACPI_MODULE_NAME("amba");
  * @periphid: AMBA device periphid.
  * @fixed_rate: Clock frequency.
  * @pdata: Platform data specific to the device.
+ * @quirk: Specific device config, including device multiattach.
+ * and mem base offset.
  *
  * Check if the given @adev can be represented as an AMBA device and, if
  * that's the case, create and register an AMBA device, populate its
@@ -42,7 +44,8 @@ ACPI_MODULE_NAME("amba");
 struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 					    unsigned int periphid,
 					    unsigned long fixed_rate,
-					    void *pdata)
+					    void *pdata,
+					    struct acpi_amba_quirk *quirk)
 {
 	struct amba_device *amba_dev = NULL;
 	struct device *parent;
@@ -54,12 +57,14 @@ struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 	unsigned int i;
 	unsigned int irq[AMBA_NR_IRQS];
 	struct clk *clk = ERR_PTR(-ENODEV);
+	char amba_devname[100];
 
 	/*
 	 * If the ACPI node already has a physical device attached,
-	 * skip it.
+	 * skip it. Except some special devices such as AMD0020 which
+	 * needs attach physical devices two times.
 	 */
-	if (adev->physical_node_count)
+	if (adev->physical_node_count && !(quirk->quirk & MULTI_ATTACHED_QUIRK))
 		return NULL;
 
 	INIT_LIST_HEAD(&resource_list);
@@ -85,7 +90,24 @@ struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 			memcpy(resource, rentry->res, sizeof(struct resource));
 	}
 
-	amba_dev = amba_device_alloc(dev_name(&adev->dev),
+	/*
+	 * The memory address of AMD pl330 has an offset of ACPI
+	 * mem resource.
+	 */
+	if (quirk->quirk & BASE_OFFSET_QUIRK)
+		resource->start += quirk->base_offset;
+
+	/*
+	 * If the ACPI device already has a node attached. It must be
+	 * renamed.
+	 */
+	if (quirk->quirk & MULTI_ATTACHED_QUIRK)
+		sprintf(amba_devname, "%s%s", dev_name(&adev->dev), "DMA");
+	else
+		memcpy(amba_devname, dev_name(&adev->dev),
+		       strlen(dev_name(&adev->dev)));
+
+	amba_dev = amba_device_alloc(amba_devname,
 				     resource->start,
 				     resource_size(resource));
 
@@ -136,6 +158,7 @@ struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 	if (ret)
 		goto amba_register_err;
 
+	amba_dev->dev.init_name = NULL;
 	ret = amba_device_add(amba_dev, resource);
 	if (ret)
 		goto amba_register_err;
diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index a450e7a..eb3316a 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -3,7 +3,8 @@
  *
  * Copyright (c) 2014,2015 AMD Corporation.
  * Authors: Ken Xue <Ken.Xue@amd.com>
- *	Wu, Jeff <Jeff.Wu@amd.com>
+ *          Jeff Wu <15618388108@163.com>
+ *	    Wang Hongcheng <Annie.Wang@amd.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -17,6 +18,10 @@
 #include <linux/acpi.h>
 #include <linux/err.h>
 #include <linux/pm.h>
+#include <linux/amba/bus.h>
+#include <linux/kernel.h>
+#include <linux/sizes.h>
+#include <linux/interrupt.h>
 
 #include "internal.h"
 
@@ -31,14 +36,15 @@ struct apd_private_data;
 #define ACPI_APD_PM	BIT(1)
 
 /**
- * struct apd_device_desc - a descriptor for apd device
- * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM
+ * struct apd_device_desc - a descriptor for apd device.
+ * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM;
  * @fixed_clk_rate: fixed rate input clock source for acpi device;
- *			0 means no fixed rate input clock source
- * @setup: a hook routine to set device resource during create platform device
+ *0 means no fixed rate input clock source;
+ * @clk_con_id: name of input clock source;
+ * @setup: a hook routine to set device resource during create platform device.
  *
- * Device description defined as acpi_device_id.driver_data
- */
+ * Device description defined as acpi_device_id.driver_data.
+*/
 struct apd_device_desc {
 	unsigned int flags;
 	unsigned int fixed_clk_rate;
@@ -71,6 +77,15 @@ static int acpi_apd_setup(struct apd_private_data *pdata)
 	return 0;
 }
 
+static void setup_quirks(struct platform_device *pdev,
+			 struct acpi_amba_quirk *quirk)
+{
+	if (!strncmp(pdev->name, "AMD0020", 7)) {
+		quirk->quirk |= MULTI_ATTACHED_QUIRK | BASE_OFFSET_QUIRK;
+		quirk->base_offset = SZ_4K;
+	}
+}
+
 static struct apd_device_desc cz_i2c_desc = {
 	.setup = acpi_apd_setup,
 	.fixed_clk_rate = 133000000,
@@ -88,15 +103,17 @@ static struct apd_device_desc cz_uart_desc = {
 #endif /* CONFIG_X86_AMD_PLATFORM_DEVICE */
 
 /**
-* Create platform device during acpi scan attach handle.
-* Return value > 0 on success of creating device.
-*/
+ * Create platform device during acpi scan attach handle.
+ * Return value > 0 on success of creating device.
+ */
 static int acpi_apd_create_device(struct acpi_device *adev,
-				   const struct acpi_device_id *id)
+				  const struct acpi_device_id *id)
 {
 	const struct apd_device_desc *dev_desc = (void *)id->driver_data;
 	struct apd_private_data *pdata;
 	struct platform_device *pdev;
+	struct amba_device *amba_dev;
+	struct acpi_amba_quirk amba_quirks;
 	int ret;
 
 	if (!dev_desc) {
@@ -118,9 +135,22 @@ static int acpi_apd_create_device(struct acpi_device *adev,
 	}
 
 	adev->driver_data = pdata;
+
 	pdev = acpi_create_platform_device(adev);
-	if (!IS_ERR_OR_NULL(pdev))
-		return 1;
+	if (IS_ERR_OR_NULL(pdev))
+		goto err_out;
+
+	if (!strncmp(pdev->name, "AMD0020", 7)) {
+		memset(&amba_quirks, 0, sizeof(amba_quirks));
+		setup_quirks(pdev, &amba_quirks);
+
+		amba_dev = acpi_create_amba_device(pdata->adev, 0x00041330,
+						   48000000,
+						   NULL,
+						   &amba_quirks);
+		if (IS_ERR_OR_NULL(amba_dev))
+			goto err_out;
+	}
 
 	ret = PTR_ERR(pdev);
 	adev->driver_data = NULL;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 04827d8..50961a5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -468,19 +468,28 @@ void acpi_walk_dep_device_list(acpi_handle handle);
 
 struct platform_device *acpi_create_platform_device(struct acpi_device *);
 
+struct acpi_amba_quirk {
+	u32 quirk;
+#define MULTI_ATTACHED_QUIRK  BIT(0)
+#define BASE_OFFSET_QUIRK     BIT(1)
+	u32 base_offset;
+};
+
 #ifdef CONFIG_ARM_AMBA
 
 struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 					    unsigned int periphid,
 					    unsigned long fixed_rate,
-					    void *pdata);
+					    void *pdata,
+					    struct acpi_amba_quirk *quirk);
 
 #else /* !CONFIG_ARM_AMBA */
 
 static inline struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 							  unsigned int periphid,
 							  unsigned long fixed_rate,
-							  void *pdata)
+							  void *pdata,
+							  struct acpi_amba_quirk *quirk)
 {
 	return NULL;
 }
-- 
1.9.1

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

* [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config
@ 2015-12-04  3:24   ` Wang Hongcheng
  0 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

AMD pl330 is a UART DMA device, it shares one ACPI item with UART. So
a platform device and an acpi device will be created according to
AMD0020 ACPI dev. And its mem base address must have an offset. As a
result, MULTI_ATTACHED_QUIRK and MULTI_ATTACHED_QUIRK are used.

Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/acpi/acpi_amba.c | 31 +++++++++++++++++++++++----
 drivers/acpi/acpi_apd.c  | 56 +++++++++++++++++++++++++++++++++++++-----------
 include/linux/acpi.h     | 13 +++++++++--
 3 files changed, 81 insertions(+), 19 deletions(-)

diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
index 4f0366a..8a5269c 100644
--- a/drivers/acpi/acpi_amba.c
+++ b/drivers/acpi/acpi_amba.c
@@ -31,6 +31,8 @@ ACPI_MODULE_NAME("amba");
  * @periphid: AMBA device periphid.
  * @fixed_rate: Clock frequency.
  * @pdata: Platform data specific to the device.
+ * @quirk: Specific device config, including device multiattach.
+ * and mem base offset.
  *
  * Check if the given @adev can be represented as an AMBA device and, if
  * that's the case, create and register an AMBA device, populate its
@@ -42,7 +44,8 @@ ACPI_MODULE_NAME("amba");
 struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 					    unsigned int periphid,
 					    unsigned long fixed_rate,
-					    void *pdata)
+					    void *pdata,
+					    struct acpi_amba_quirk *quirk)
 {
 	struct amba_device *amba_dev = NULL;
 	struct device *parent;
@@ -54,12 +57,14 @@ struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 	unsigned int i;
 	unsigned int irq[AMBA_NR_IRQS];
 	struct clk *clk = ERR_PTR(-ENODEV);
+	char amba_devname[100];
 
 	/*
 	 * If the ACPI node already has a physical device attached,
-	 * skip it.
+	 * skip it. Except some special devices such as AMD0020 which
+	 * needs attach physical devices two times.
 	 */
-	if (adev->physical_node_count)
+	if (adev->physical_node_count && !(quirk->quirk & MULTI_ATTACHED_QUIRK))
 		return NULL;
 
 	INIT_LIST_HEAD(&resource_list);
@@ -85,7 +90,24 @@ struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 			memcpy(resource, rentry->res, sizeof(struct resource));
 	}
 
-	amba_dev = amba_device_alloc(dev_name(&adev->dev),
+	/*
+	 * The memory address of AMD pl330 has an offset of ACPI
+	 * mem resource.
+	 */
+	if (quirk->quirk & BASE_OFFSET_QUIRK)
+		resource->start += quirk->base_offset;
+
+	/*
+	 * If the ACPI device already has a node attached. It must be
+	 * renamed.
+	 */
+	if (quirk->quirk & MULTI_ATTACHED_QUIRK)
+		sprintf(amba_devname, "%s%s", dev_name(&adev->dev), "DMA");
+	else
+		memcpy(amba_devname, dev_name(&adev->dev),
+		       strlen(dev_name(&adev->dev)));
+
+	amba_dev = amba_device_alloc(amba_devname,
 				     resource->start,
 				     resource_size(resource));
 
@@ -136,6 +158,7 @@ struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 	if (ret)
 		goto amba_register_err;
 
+	amba_dev->dev.init_name = NULL;
 	ret = amba_device_add(amba_dev, resource);
 	if (ret)
 		goto amba_register_err;
diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index a450e7a..eb3316a 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -3,7 +3,8 @@
  *
  * Copyright (c) 2014,2015 AMD Corporation.
  * Authors: Ken Xue <Ken.Xue@amd.com>
- *	Wu, Jeff <Jeff.Wu@amd.com>
+ *          Jeff Wu <15618388108@163.com>
+ *	    Wang Hongcheng <Annie.Wang@amd.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -17,6 +18,10 @@
 #include <linux/acpi.h>
 #include <linux/err.h>
 #include <linux/pm.h>
+#include <linux/amba/bus.h>
+#include <linux/kernel.h>
+#include <linux/sizes.h>
+#include <linux/interrupt.h>
 
 #include "internal.h"
 
@@ -31,14 +36,15 @@ struct apd_private_data;
 #define ACPI_APD_PM	BIT(1)
 
 /**
- * struct apd_device_desc - a descriptor for apd device
- * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM
+ * struct apd_device_desc - a descriptor for apd device.
+ * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM;
  * @fixed_clk_rate: fixed rate input clock source for acpi device;
- *			0 means no fixed rate input clock source
- * @setup: a hook routine to set device resource during create platform device
+ *0 means no fixed rate input clock source;
+ * @clk_con_id: name of input clock source;
+ * @setup: a hook routine to set device resource during create platform device.
  *
- * Device description defined as acpi_device_id.driver_data
- */
+ * Device description defined as acpi_device_id.driver_data.
+*/
 struct apd_device_desc {
 	unsigned int flags;
 	unsigned int fixed_clk_rate;
@@ -71,6 +77,15 @@ static int acpi_apd_setup(struct apd_private_data *pdata)
 	return 0;
 }
 
+static void setup_quirks(struct platform_device *pdev,
+			 struct acpi_amba_quirk *quirk)
+{
+	if (!strncmp(pdev->name, "AMD0020", 7)) {
+		quirk->quirk |= MULTI_ATTACHED_QUIRK | BASE_OFFSET_QUIRK;
+		quirk->base_offset = SZ_4K;
+	}
+}
+
 static struct apd_device_desc cz_i2c_desc = {
 	.setup = acpi_apd_setup,
 	.fixed_clk_rate = 133000000,
@@ -88,15 +103,17 @@ static struct apd_device_desc cz_uart_desc = {
 #endif /* CONFIG_X86_AMD_PLATFORM_DEVICE */
 
 /**
-* Create platform device during acpi scan attach handle.
-* Return value > 0 on success of creating device.
-*/
+ * Create platform device during acpi scan attach handle.
+ * Return value > 0 on success of creating device.
+ */
 static int acpi_apd_create_device(struct acpi_device *adev,
-				   const struct acpi_device_id *id)
+				  const struct acpi_device_id *id)
 {
 	const struct apd_device_desc *dev_desc = (void *)id->driver_data;
 	struct apd_private_data *pdata;
 	struct platform_device *pdev;
+	struct amba_device *amba_dev;
+	struct acpi_amba_quirk amba_quirks;
 	int ret;
 
 	if (!dev_desc) {
@@ -118,9 +135,22 @@ static int acpi_apd_create_device(struct acpi_device *adev,
 	}
 
 	adev->driver_data = pdata;
+
 	pdev = acpi_create_platform_device(adev);
-	if (!IS_ERR_OR_NULL(pdev))
-		return 1;
+	if (IS_ERR_OR_NULL(pdev))
+		goto err_out;
+
+	if (!strncmp(pdev->name, "AMD0020", 7)) {
+		memset(&amba_quirks, 0, sizeof(amba_quirks));
+		setup_quirks(pdev, &amba_quirks);
+
+		amba_dev = acpi_create_amba_device(pdata->adev, 0x00041330,
+						   48000000,
+						   NULL,
+						   &amba_quirks);
+		if (IS_ERR_OR_NULL(amba_dev))
+			goto err_out;
+	}
 
 	ret = PTR_ERR(pdev);
 	adev->driver_data = NULL;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 04827d8..50961a5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -468,19 +468,28 @@ void acpi_walk_dep_device_list(acpi_handle handle);
 
 struct platform_device *acpi_create_platform_device(struct acpi_device *);
 
+struct acpi_amba_quirk {
+	u32 quirk;
+#define MULTI_ATTACHED_QUIRK  BIT(0)
+#define BASE_OFFSET_QUIRK     BIT(1)
+	u32 base_offset;
+};
+
 #ifdef CONFIG_ARM_AMBA
 
 struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 					    unsigned int periphid,
 					    unsigned long fixed_rate,
-					    void *pdata);
+					    void *pdata,
+					    struct acpi_amba_quirk *quirk);
 
 #else /* !CONFIG_ARM_AMBA */
 
 static inline struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
 							  unsigned int periphid,
 							  unsigned long fixed_rate,
-							  void *pdata)
+							  void *pdata,
+							  struct acpi_amba_quirk *quirk)
 {
 	return NULL;
 }
-- 
1.9.1


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

* [PATCH 4/9] dmaengine: pl330: add new items for pl330 private data
  2015-12-04  3:24 ` Wang Hongcheng
@ 2015-12-04  3:24   ` Wang Hongcheng
  -1 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

has_no_cap_mask means this device has no preset cap mask.
mcbuf_sz means bytes to allocate for MC buffer.
flags is for irq sharing, default is non-shared, in AMD
Carrizo, pl330 shares IRQ with its corresponding UART device.

Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/acpi/acpi_apd.c    | 13 ++++++++++++-
 drivers/dma/pl330.c        | 19 +++++++++++++------
 include/linux/amba/pl330.h |  3 +++
 3 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index eb3316a..7a582f5 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -21,6 +21,7 @@
 #include <linux/amba/bus.h>
 #include <linux/kernel.h>
 #include <linux/sizes.h>
+#include <linux/amba/pl330.h>
 #include <linux/interrupt.h>
 
 #include "internal.h"
@@ -35,6 +36,16 @@ struct apd_private_data;
 #define ACPI_APD_SYSFS	BIT(0)
 #define ACPI_APD_PM	BIT(1)
 
+static u8 peri_id[2] = { 0, 1 };
+
+static struct dma_pl330_platdata amd_pl330 = {
+	.nr_valid_peri = 2,
+	.peri_id = peri_id,
+	.has_no_cap_mask = true,
+	.mcbuf_sz = 0,
+	.flags = IRQF_SHARED,
+};
+
 /**
  * struct apd_device_desc - a descriptor for apd device.
  * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM;
@@ -146,7 +157,7 @@ static int acpi_apd_create_device(struct acpi_device *adev,
 
 		amba_dev = acpi_create_amba_device(pdata->adev, 0x00041330,
 						   48000000,
-						   NULL,
+						   &amd_pl330,
 						   &amba_quirks);
 		if (IS_ERR_OR_NULL(amba_dev))
 			goto err_out;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 17ee758..8300969 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -26,6 +26,8 @@
 #include <linux/scatterlist.h>
 #include <linux/of.h>
 #include <linux/of_dma.h>
+#include <linux/acpi.h>
+#include <linux/acpi_dma.h>
 #include <linux/err.h>
 #include <linux/pm_runtime.h>
 
@@ -488,6 +490,9 @@ struct pl330_dmac {
 	/* Peripheral channels connected to this DMAC */
 	unsigned int num_peripherals;
 	struct dma_pl330_chan *peripherals; /* keep at end */
+
+	/*IRQ register flags */
+	unsigned int flags;
 };
 
 struct dma_pl330_desc {
@@ -2800,6 +2805,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0;
 
+	pl330->flags = pdat ? pdat->flags : IRQF_TRIGGER_NONE;
+
 	res = &adev->res;
 	pl330->base = devm_ioremap_resource(&adev->dev, res);
 	if (IS_ERR(pl330->base))
@@ -2811,7 +2818,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		irq = adev->irq[i];
 		if (irq) {
 			ret = devm_request_irq(&adev->dev, irq,
-					       pl330_irq_handler, 0,
+					       pl330_irq_handler, pl330->flags,
 					       dev_name(&adev->dev), pl330);
 			if (ret)
 				return ret;
@@ -2870,7 +2877,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		list_add_tail(&pch->chan.device_node, &pd->channels);
 	}
 
-	if (pdat) {
+	if (pdat && !pdat->has_no_cap_mask) {
 		pd->cap_mask = pdat->cap_mask;
 	} else {
 		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
@@ -2923,11 +2930,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 
 	dev_info(&adev->dev,
-		"Loaded driver for PL330 DMAC-%x\n", adev->periphid);
+		 "Loaded driver for PL330 DMAC-%x\n", adev->periphid);
 	dev_info(&adev->dev,
-		"\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
-		pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan,
-		pcfg->num_peri, pcfg->num_events);
+		 "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
+		 pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan,
+		 pcfg->num_peri, pcfg->num_events);
 
 	pm_runtime_irq_safe(&adev->dev);
 	pm_runtime_use_autosuspend(&adev->dev);
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index fe93758..605d00f 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -26,9 +26,12 @@ struct dma_pl330_platdata {
 	/* Array of valid peripherals */
 	u8 *peri_id;
 	/* Operational capabilities */
+	bool has_no_cap_mask;
 	dma_cap_mask_t cap_mask;
 	/* Bytes to allocate for MC buffer */
 	unsigned mcbuf_sz;
+	/*flags for irq sharing, default is non-shared*/
+	unsigned flags;
 };
 
 extern bool pl330_filter(struct dma_chan *chan, void *param);
-- 
1.9.1


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

* [PATCH 4/9] dmaengine: pl330: add new items for pl330 private data
@ 2015-12-04  3:24   ` Wang Hongcheng
  0 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

has_no_cap_mask means this device has no preset cap mask.
mcbuf_sz means bytes to allocate for MC buffer.
flags is for irq sharing, default is non-shared, in AMD
Carrizo, pl330 shares IRQ with its corresponding UART device.

Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/acpi/acpi_apd.c    | 13 ++++++++++++-
 drivers/dma/pl330.c        | 19 +++++++++++++------
 include/linux/amba/pl330.h |  3 +++
 3 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index eb3316a..7a582f5 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -21,6 +21,7 @@
 #include <linux/amba/bus.h>
 #include <linux/kernel.h>
 #include <linux/sizes.h>
+#include <linux/amba/pl330.h>
 #include <linux/interrupt.h>
 
 #include "internal.h"
@@ -35,6 +36,16 @@ struct apd_private_data;
 #define ACPI_APD_SYSFS	BIT(0)
 #define ACPI_APD_PM	BIT(1)
 
+static u8 peri_id[2] = { 0, 1 };
+
+static struct dma_pl330_platdata amd_pl330 = {
+	.nr_valid_peri = 2,
+	.peri_id = peri_id,
+	.has_no_cap_mask = true,
+	.mcbuf_sz = 0,
+	.flags = IRQF_SHARED,
+};
+
 /**
  * struct apd_device_desc - a descriptor for apd device.
  * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM;
@@ -146,7 +157,7 @@ static int acpi_apd_create_device(struct acpi_device *adev,
 
 		amba_dev = acpi_create_amba_device(pdata->adev, 0x00041330,
 						   48000000,
-						   NULL,
+						   &amd_pl330,
 						   &amba_quirks);
 		if (IS_ERR_OR_NULL(amba_dev))
 			goto err_out;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 17ee758..8300969 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -26,6 +26,8 @@
 #include <linux/scatterlist.h>
 #include <linux/of.h>
 #include <linux/of_dma.h>
+#include <linux/acpi.h>
+#include <linux/acpi_dma.h>
 #include <linux/err.h>
 #include <linux/pm_runtime.h>
 
@@ -488,6 +490,9 @@ struct pl330_dmac {
 	/* Peripheral channels connected to this DMAC */
 	unsigned int num_peripherals;
 	struct dma_pl330_chan *peripherals; /* keep at end */
+
+	/*IRQ register flags */
+	unsigned int flags;
 };
 
 struct dma_pl330_desc {
@@ -2800,6 +2805,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0;
 
+	pl330->flags = pdat ? pdat->flags : IRQF_TRIGGER_NONE;
+
 	res = &adev->res;
 	pl330->base = devm_ioremap_resource(&adev->dev, res);
 	if (IS_ERR(pl330->base))
@@ -2811,7 +2818,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		irq = adev->irq[i];
 		if (irq) {
 			ret = devm_request_irq(&adev->dev, irq,
-					       pl330_irq_handler, 0,
+					       pl330_irq_handler, pl330->flags,
 					       dev_name(&adev->dev), pl330);
 			if (ret)
 				return ret;
@@ -2870,7 +2877,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		list_add_tail(&pch->chan.device_node, &pd->channels);
 	}
 
-	if (pdat) {
+	if (pdat && !pdat->has_no_cap_mask) {
 		pd->cap_mask = pdat->cap_mask;
 	} else {
 		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
@@ -2923,11 +2930,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 
 	dev_info(&adev->dev,
-		"Loaded driver for PL330 DMAC-%x\n", adev->periphid);
+		 "Loaded driver for PL330 DMAC-%x\n", adev->periphid);
 	dev_info(&adev->dev,
-		"\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
-		pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan,
-		pcfg->num_peri, pcfg->num_events);
+		 "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
+		 pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan,
+		 pcfg->num_peri, pcfg->num_events);
 
 	pm_runtime_irq_safe(&adev->dev);
 	pm_runtime_use_autosuspend(&adev->dev);
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index fe93758..605d00f 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -26,9 +26,12 @@ struct dma_pl330_platdata {
 	/* Array of valid peripherals */
 	u8 *peri_id;
 	/* Operational capabilities */
+	bool has_no_cap_mask;
 	dma_cap_mask_t cap_mask;
 	/* Bytes to allocate for MC buffer */
 	unsigned mcbuf_sz;
+	/*flags for irq sharing, default is non-shared*/
+	unsigned flags;
 };
 
 extern bool pl330_filter(struct dma_chan *chan, void *param);
-- 
1.9.1


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

* [PATCH 5/9] dmaengine: pl330: provide ACPI dmaengine interface
  2015-12-04  3:24 ` Wang Hongcheng
@ 2015-12-04  3:24   ` Wang Hongcheng
  -1 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

register acpi_dma controller, so ACPI devices can request pl330 DMA
channel.
A filter is added in private data for Carrizo specific hardware
design

Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/acpi/acpi_apd.c    | 12 ++++++++++++
 drivers/dma/pl330.c        | 38 ++++++++++++++++++++++++++++++++++++++
 include/linux/amba/pl330.h |  1 +
 3 files changed, 51 insertions(+)

diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index 7a582f5..906a20f 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -38,12 +38,15 @@ struct apd_private_data;
 
 static u8 peri_id[2] = { 0, 1 };
 
+static int apd_acpi_xlate_filter(int slave_id, struct device *dev);
+
 static struct dma_pl330_platdata amd_pl330 = {
 	.nr_valid_peri = 2,
 	.peri_id = peri_id,
 	.has_no_cap_mask = true,
 	.mcbuf_sz = 0,
 	.flags = IRQF_SHARED,
+	.acpi_xlate_filter = apd_acpi_xlate_filter,
 };
 
 /**
@@ -68,6 +71,15 @@ struct apd_private_data {
 	const struct apd_device_desc *dev_desc;
 };
 
+int apd_acpi_xlate_filter(int slave_id, struct device *dev)
+{
+	if (((slave_id == 1) && (!strcmp(dev_name(dev), "AMD0020:00DMA")))
+	    || ((slave_id == 2) && (!strcmp(dev_name(dev), "AMD0020:01DMA"))))
+		return 0;
+
+	return 1;
+}
+
 #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
 #define APD_ADDR(desc)	((unsigned long)&desc)
 
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 8300969..9d7af0d 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2079,6 +2079,35 @@ static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec,
 	return dma_get_slave_channel(&pl330->peripherals[chan_id].chan);
 }
 
+static struct dma_chan *acpi_dma_pl330_xlate(struct acpi_dma_spec *dma_spec,
+					     struct acpi_dma *adma)
+{
+	struct pl330_dmac *pl330 = adma->data;
+	struct dma_pl330_platdata *pdat;
+	unsigned int chan_id;
+	int ret;
+
+	if (!dma_spec)
+		return NULL;
+
+	if (!adma)
+		return NULL;
+
+	pdat = dev_get_platdata(adma->dev);
+
+	chan_id = dma_spec->chan_id;
+	if (chan_id >= pl330->num_peripherals)
+		return NULL;
+
+	if (pdat->acpi_xlate_filter) {
+		ret = pdat->acpi_xlate_filter(dma_spec->slave_id, adma->dev);
+		if (ret)
+			return NULL;
+	}
+
+	return dma_get_slave_channel(&pl330->peripherals[chan_id].chan);
+}
+
 static int pl330_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct dma_pl330_chan *pch = to_pchan(chan);
@@ -2918,6 +2947,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		}
 	}
 
+	if (ACPI_HANDLE(&adev->dev)) {
+		ret = acpi_dma_controller_register(&adev->dev,
+						   acpi_dma_pl330_xlate, pl330);
+		if (ret) {
+			dev_err(&adev->dev,
+				"unable to register DMA to the generic ACPI DMA helpers\n");
+		}
+	}
+
 	adev->dev.dma_parms = &pl330->dma_parms;
 
 	/*
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index 605d00f..85bebbb 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -32,6 +32,7 @@ struct dma_pl330_platdata {
 	unsigned mcbuf_sz;
 	/*flags for irq sharing, default is non-shared*/
 	unsigned flags;
+	int (*acpi_xlate_filter)(int slave_id, struct device *dev);
 };
 
 extern bool pl330_filter(struct dma_chan *chan, void *param);
-- 
1.9.1

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

* [PATCH 5/9] dmaengine: pl330: provide ACPI dmaengine interface
@ 2015-12-04  3:24   ` Wang Hongcheng
  0 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

register acpi_dma controller, so ACPI devices can request pl330 DMA
channel.
A filter is added in private data for Carrizo specific hardware
design

Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/acpi/acpi_apd.c    | 12 ++++++++++++
 drivers/dma/pl330.c        | 38 ++++++++++++++++++++++++++++++++++++++
 include/linux/amba/pl330.h |  1 +
 3 files changed, 51 insertions(+)

diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index 7a582f5..906a20f 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -38,12 +38,15 @@ struct apd_private_data;
 
 static u8 peri_id[2] = { 0, 1 };
 
+static int apd_acpi_xlate_filter(int slave_id, struct device *dev);
+
 static struct dma_pl330_platdata amd_pl330 = {
 	.nr_valid_peri = 2,
 	.peri_id = peri_id,
 	.has_no_cap_mask = true,
 	.mcbuf_sz = 0,
 	.flags = IRQF_SHARED,
+	.acpi_xlate_filter = apd_acpi_xlate_filter,
 };
 
 /**
@@ -68,6 +71,15 @@ struct apd_private_data {
 	const struct apd_device_desc *dev_desc;
 };
 
+int apd_acpi_xlate_filter(int slave_id, struct device *dev)
+{
+	if (((slave_id == 1) && (!strcmp(dev_name(dev), "AMD0020:00DMA")))
+	    || ((slave_id == 2) && (!strcmp(dev_name(dev), "AMD0020:01DMA"))))
+		return 0;
+
+	return 1;
+}
+
 #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
 #define APD_ADDR(desc)	((unsigned long)&desc)
 
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 8300969..9d7af0d 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2079,6 +2079,35 @@ static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec,
 	return dma_get_slave_channel(&pl330->peripherals[chan_id].chan);
 }
 
+static struct dma_chan *acpi_dma_pl330_xlate(struct acpi_dma_spec *dma_spec,
+					     struct acpi_dma *adma)
+{
+	struct pl330_dmac *pl330 = adma->data;
+	struct dma_pl330_platdata *pdat;
+	unsigned int chan_id;
+	int ret;
+
+	if (!dma_spec)
+		return NULL;
+
+	if (!adma)
+		return NULL;
+
+	pdat = dev_get_platdata(adma->dev);
+
+	chan_id = dma_spec->chan_id;
+	if (chan_id >= pl330->num_peripherals)
+		return NULL;
+
+	if (pdat->acpi_xlate_filter) {
+		ret = pdat->acpi_xlate_filter(dma_spec->slave_id, adma->dev);
+		if (ret)
+			return NULL;
+	}
+
+	return dma_get_slave_channel(&pl330->peripherals[chan_id].chan);
+}
+
 static int pl330_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct dma_pl330_chan *pch = to_pchan(chan);
@@ -2918,6 +2947,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		}
 	}
 
+	if (ACPI_HANDLE(&adev->dev)) {
+		ret = acpi_dma_controller_register(&adev->dev,
+						   acpi_dma_pl330_xlate, pl330);
+		if (ret) {
+			dev_err(&adev->dev,
+				"unable to register DMA to the generic ACPI DMA helpers\n");
+		}
+	}
+
 	adev->dev.dma_parms = &pl330->dma_parms;
 
 	/*
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index 605d00f..85bebbb 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -32,6 +32,7 @@ struct dma_pl330_platdata {
 	unsigned mcbuf_sz;
 	/*flags for irq sharing, default is non-shared*/
 	unsigned flags;
+	int (*acpi_xlate_filter)(int slave_id, struct device *dev);
 };
 
 extern bool pl330_filter(struct dma_chan *chan, void *param);
-- 
1.9.1


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

* [PATCH 6/9] dmaengine:pl330: set segment_boundary_mask = 0cffffffff
  2015-12-04  3:24 ` Wang Hongcheng
@ 2015-12-04  3:24   ` Wang Hongcheng
  -1 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng, Wan Zongshun

Because amd iommu and software iommu need this mask.For example,
if we use software iommu without this mask, we will
get 'Out of SW-IOMMU space' error, when calling swiotlb_map_page
function.

Signed-off-by: Wan Zongshun <Vincent.Wan@amd.com>
Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/dma/pl330.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 9d7af0d..fb46fdf 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2966,6 +2966,10 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	if (ret)
 		dev_err(&adev->dev, "unable to set the seg size\n");
 
+	dev_info(&adev->dev, "set the seg boundary\n");
+	ret = dma_set_seg_boundary(&adev->dev, 0xffffffff);
+	if (ret)
+		dev_err(&adev->dev, "unable to set the seg boundary\n");
 
 	dev_info(&adev->dev,
 		 "Loaded driver for PL330 DMAC-%x\n", adev->periphid);
-- 
1.9.1

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

* [PATCH 6/9] dmaengine:pl330: set segment_boundary_mask = 0cffffffff
@ 2015-12-04  3:24   ` Wang Hongcheng
  0 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng, Wan Zongshun

Because amd iommu and software iommu need this mask.For example,
if we use software iommu without this mask, we will
get 'Out of SW-IOMMU space' error, when calling swiotlb_map_page
function.

Signed-off-by: Wan Zongshun <Vincent.Wan@amd.com>
Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/dma/pl330.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 9d7af0d..fb46fdf 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2966,6 +2966,10 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	if (ret)
 		dev_err(&adev->dev, "unable to set the seg size\n");
 
+	dev_info(&adev->dev, "set the seg boundary\n");
+	ret = dma_set_seg_boundary(&adev->dev, 0xffffffff);
+	if (ret)
+		dev_err(&adev->dev, "unable to set the seg boundary\n");
 
 	dev_info(&adev->dev,
 		 "Loaded driver for PL330 DMAC-%x\n", adev->periphid);
-- 
1.9.1


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

* [PATCH 7/9] Serial:8250: New Port Type PORT_AMD_8250
  2015-12-04  3:24 ` Wang Hongcheng
@ 2015-12-04  3:24   ` Wang Hongcheng
  -1 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

Set a new port type for AMD Carrizo.  Add has_pl330_dma to 8250_dw's
private data and init fcr,ier as well as dma rx size.

Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/acpi/acpi_apd.c             | 10 ++++++++++
 drivers/tty/serial/8250/8250_dw.c   | 16 ++++++++++++++++
 drivers/tty/serial/8250/8250_port.c |  9 +++++++++
 include/linux/serial_8250.h         |  4 ++++
 include/uapi/linux/serial_core.h    |  3 ++-
 include/uapi/linux/serial_reg.h     |  2 ++
 6 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index 906a20f..787f477 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -23,6 +23,7 @@
 #include <linux/sizes.h>
 #include <linux/amba/pl330.h>
 #include <linux/interrupt.h>
+#include <linux/serial_8250.h>
 
 #include "internal.h"
 
@@ -49,6 +50,10 @@ static struct dma_pl330_platdata amd_pl330 = {
 	.acpi_xlate_filter = apd_acpi_xlate_filter,
 };
 
+static struct plat_dw8250_data amd_dw8250 = {
+	.has_pl330_dma = 1,
+};
+
 /**
  * struct apd_device_desc - a descriptor for apd device.
  * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM;
@@ -164,6 +169,11 @@ static int acpi_apd_create_device(struct acpi_device *adev,
 		goto err_out;
 
 	if (!strncmp(pdev->name, "AMD0020", 7)) {
+		ret = platform_device_add_data(pdev, &amd_dw8250,
+					       sizeof(amd_dw8250));
+		if (ret)
+			goto err_out;
+
 		memset(&amba_quirks, 0, sizeof(amba_quirks));
 		setup_quirks(pdev, &amba_quirks);
 
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index a5d319e..a5ae9b6 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -66,6 +66,8 @@ struct dw8250_data {
 
 	unsigned int		skip_autocfg:1;
 	unsigned int		uart_16550_compatible:1;
+
+	unsigned		has_pl330_dma:1;
 };
 
 #define BYT_PRV_CLK			0x800
@@ -304,6 +306,7 @@ static void dw8250_setup_port(struct uart_port *p)
 {
 	struct uart_8250_port *up = up_to_u8250p(p);
 	u32 reg;
+	struct dw8250_data *d = p->private_data;
 
 	/*
 	 * If the Component Version Register returns zero, we know that
@@ -326,6 +329,16 @@ static void dw8250_setup_port(struct uart_port *p)
 		p->flags |= UPF_FIXED_TYPE;
 		p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
 		up->capabilities = UART_CAP_FIFO;
+		if (d->has_pl330_dma) {
+			p->type = PORT_AMD_8250;
+			p->flags |= UPF_SHARE_IRQ;
+
+			up->ier |= UART_IER_PTIME | UART_IER_THRI |
+				UART_IER_RLSI | UART_IER_RDI;
+			up->fcr |= UART_FCR_R_TRIG_10 | UART_FCR_T_TRIG_11 |
+				UART_FCR_DMA_SELECT;
+			up->tx_loadsz = p->fifosize / 2;
+		}
 	}
 
 	if (reg & DW_UART_CPR_AFCE_MODE)
@@ -339,6 +352,7 @@ static int dw8250_probe(struct platform_device *pdev)
 	int irq = platform_get_irq(pdev, 0);
 	struct uart_port *p = &uart.port;
 	struct dw8250_data *data;
+	struct plat_dw8250_data *pdata = dev_get_platdata(&pdev->dev);
 	int err;
 	u32 val;
 
@@ -468,6 +482,7 @@ static int dw8250_probe(struct platform_device *pdev)
 		p->handle_irq = NULL;
 	}
 
+	data->has_pl330_dma = pdata ? pdata->has_pl330_dma : 0;
 	if (!data->skip_autocfg)
 		dw8250_setup_port(p);
 
@@ -475,6 +490,7 @@ static int dw8250_probe(struct platform_device *pdev)
 	if (p->fifosize) {
 		data->dma.rxconf.src_maxburst = p->fifosize / 4;
 		data->dma.txconf.dst_maxburst = p->fifosize / 4;
+		data->dma.rx_size = data->has_pl330_dma ? (p->fifosize / 2 + 2) : 0;
 		uart.dma = &data->dma;
 	}
 
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 52d82d2..b258edc 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -269,6 +269,15 @@ configured less than Maximum supported fifo bytes */
 		.rxtrig_bytes	= {1, 4, 8, 14},
 		.flags		= UART_CAP_FIFO,
 	},
+	[PORT_AMD_8250] = {
+		.name		= "AMD_8250",
+		.fifo_size	= 256,
+		.tx_loadsz	= 128,
+		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
+				UART_FCR_T_TRIG_11 | UART_FCR_DMA_SELECT,
+		.rxtrig_bytes	= {1, 4, 8},
+		.flags		= UART_CAP_FIFO,
+	},
 };
 
 /* Uart divisor latch read */
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index faa0e03..4652783 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -42,6 +42,10 @@ struct plat_serial8250_port {
 	void		(*handle_break)(struct uart_port *);
 };
 
+struct plat_dw8250_data {
+	unsigned has_pl330_dma:1;
+};
+
 /*
  * Allocate 8250 platform device IDs.  Nothing is implied by
  * the numbering here, except for the legacy entry being -1.
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 93ba148..6a06651 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -56,7 +56,8 @@
 #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */
 #define PORT_RT2880	29	/* Ralink RT2880 internal UART */
 #define PORT_16550A_FSL64 30	/* Freescale 16550 UART with 64 FIFOs */
-#define PORT_MAX_8250	30	/* max port ID */
+#define PORT_AMD_8250  31
+#define PORT_MAX_8250	32	/* max port ID */
 
 /*
  * ARM specific type numbers.  These are not currently guaranteed
diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h
index 1e5ac4e7..13e8294 100644
--- a/include/uapi/linux/serial_reg.h
+++ b/include/uapi/linux/serial_reg.h
@@ -25,6 +25,8 @@
 #define UART_IER_RLSI		0x04 /* Enable receiver line status interrupt */
 #define UART_IER_THRI		0x02 /* Enable Transmitter holding register int. */
 #define UART_IER_RDI		0x01 /* Enable receiver data interrupt */
+/* Enable Programmable Transmitter holding register int. */
+#define UART_IER_PTIME          0x80
 /*
  * Sleep mode for ST16650 and TI16750.  For the ST16650, EFR[4]=1
  */
-- 
1.9.1


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

* [PATCH 7/9] Serial:8250: New Port Type PORT_AMD_8250
@ 2015-12-04  3:24   ` Wang Hongcheng
  0 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wang Hongcheng

Set a new port type for AMD Carrizo.  Add has_pl330_dma to 8250_dw's
private data and init fcr,ier as well as dma rx size.

Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
---
 drivers/acpi/acpi_apd.c             | 10 ++++++++++
 drivers/tty/serial/8250/8250_dw.c   | 16 ++++++++++++++++
 drivers/tty/serial/8250/8250_port.c |  9 +++++++++
 include/linux/serial_8250.h         |  4 ++++
 include/uapi/linux/serial_core.h    |  3 ++-
 include/uapi/linux/serial_reg.h     |  2 ++
 6 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index 906a20f..787f477 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -23,6 +23,7 @@
 #include <linux/sizes.h>
 #include <linux/amba/pl330.h>
 #include <linux/interrupt.h>
+#include <linux/serial_8250.h>
 
 #include "internal.h"
 
@@ -49,6 +50,10 @@ static struct dma_pl330_platdata amd_pl330 = {
 	.acpi_xlate_filter = apd_acpi_xlate_filter,
 };
 
+static struct plat_dw8250_data amd_dw8250 = {
+	.has_pl330_dma = 1,
+};
+
 /**
  * struct apd_device_desc - a descriptor for apd device.
  * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM;
@@ -164,6 +169,11 @@ static int acpi_apd_create_device(struct acpi_device *adev,
 		goto err_out;
 
 	if (!strncmp(pdev->name, "AMD0020", 7)) {
+		ret = platform_device_add_data(pdev, &amd_dw8250,
+					       sizeof(amd_dw8250));
+		if (ret)
+			goto err_out;
+
 		memset(&amba_quirks, 0, sizeof(amba_quirks));
 		setup_quirks(pdev, &amba_quirks);
 
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index a5d319e..a5ae9b6 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -66,6 +66,8 @@ struct dw8250_data {
 
 	unsigned int		skip_autocfg:1;
 	unsigned int		uart_16550_compatible:1;
+
+	unsigned		has_pl330_dma:1;
 };
 
 #define BYT_PRV_CLK			0x800
@@ -304,6 +306,7 @@ static void dw8250_setup_port(struct uart_port *p)
 {
 	struct uart_8250_port *up = up_to_u8250p(p);
 	u32 reg;
+	struct dw8250_data *d = p->private_data;
 
 	/*
 	 * If the Component Version Register returns zero, we know that
@@ -326,6 +329,16 @@ static void dw8250_setup_port(struct uart_port *p)
 		p->flags |= UPF_FIXED_TYPE;
 		p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
 		up->capabilities = UART_CAP_FIFO;
+		if (d->has_pl330_dma) {
+			p->type = PORT_AMD_8250;
+			p->flags |= UPF_SHARE_IRQ;
+
+			up->ier |= UART_IER_PTIME | UART_IER_THRI |
+				UART_IER_RLSI | UART_IER_RDI;
+			up->fcr |= UART_FCR_R_TRIG_10 | UART_FCR_T_TRIG_11 |
+				UART_FCR_DMA_SELECT;
+			up->tx_loadsz = p->fifosize / 2;
+		}
 	}
 
 	if (reg & DW_UART_CPR_AFCE_MODE)
@@ -339,6 +352,7 @@ static int dw8250_probe(struct platform_device *pdev)
 	int irq = platform_get_irq(pdev, 0);
 	struct uart_port *p = &uart.port;
 	struct dw8250_data *data;
+	struct plat_dw8250_data *pdata = dev_get_platdata(&pdev->dev);
 	int err;
 	u32 val;
 
@@ -468,6 +482,7 @@ static int dw8250_probe(struct platform_device *pdev)
 		p->handle_irq = NULL;
 	}
 
+	data->has_pl330_dma = pdata ? pdata->has_pl330_dma : 0;
 	if (!data->skip_autocfg)
 		dw8250_setup_port(p);
 
@@ -475,6 +490,7 @@ static int dw8250_probe(struct platform_device *pdev)
 	if (p->fifosize) {
 		data->dma.rxconf.src_maxburst = p->fifosize / 4;
 		data->dma.txconf.dst_maxburst = p->fifosize / 4;
+		data->dma.rx_size = data->has_pl330_dma ? (p->fifosize / 2 + 2) : 0;
 		uart.dma = &data->dma;
 	}
 
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 52d82d2..b258edc 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -269,6 +269,15 @@ configured less than Maximum supported fifo bytes */
 		.rxtrig_bytes	= {1, 4, 8, 14},
 		.flags		= UART_CAP_FIFO,
 	},
+	[PORT_AMD_8250] = {
+		.name		= "AMD_8250",
+		.fifo_size	= 256,
+		.tx_loadsz	= 128,
+		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
+				UART_FCR_T_TRIG_11 | UART_FCR_DMA_SELECT,
+		.rxtrig_bytes	= {1, 4, 8},
+		.flags		= UART_CAP_FIFO,
+	},
 };
 
 /* Uart divisor latch read */
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index faa0e03..4652783 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -42,6 +42,10 @@ struct plat_serial8250_port {
 	void		(*handle_break)(struct uart_port *);
 };
 
+struct plat_dw8250_data {
+	unsigned has_pl330_dma:1;
+};
+
 /*
  * Allocate 8250 platform device IDs.  Nothing is implied by
  * the numbering here, except for the legacy entry being -1.
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 93ba148..6a06651 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -56,7 +56,8 @@
 #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */
 #define PORT_RT2880	29	/* Ralink RT2880 internal UART */
 #define PORT_16550A_FSL64 30	/* Freescale 16550 UART with 64 FIFOs */
-#define PORT_MAX_8250	30	/* max port ID */
+#define PORT_AMD_8250  31
+#define PORT_MAX_8250	32	/* max port ID */
 
 /*
  * ARM specific type numbers.  These are not currently guaranteed
diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h
index 1e5ac4e7..13e8294 100644
--- a/include/uapi/linux/serial_reg.h
+++ b/include/uapi/linux/serial_reg.h
@@ -25,6 +25,8 @@
 #define UART_IER_RLSI		0x04 /* Enable receiver line status interrupt */
 #define UART_IER_THRI		0x02 /* Enable Transmitter holding register int. */
 #define UART_IER_RDI		0x01 /* Enable receiver data interrupt */
+/* Enable Programmable Transmitter holding register int. */
+#define UART_IER_PTIME          0x80
 /*
  * Sleep mode for ST16650 and TI16750.  For the ST16650, EFR[4]=1
  */
-- 
1.9.1


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

* [PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description
  2015-12-04  3:24 ` Wang Hongcheng
@ 2015-12-04  3:24   ` Wang Hongcheng
  -1 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wan Zongshun

From: Wan Zongshun <Vincent.Wan@amd.com>

Add ivrs_acpihid kernel parameter description,
like ivrs_acpihid[00:14.5]=AMD0020:0.

Signed-off-by: Wan Zongshun <Vincent.Wan@amd.com>
---
 Documentation/kernel-parameters.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 742f69d..5c364c6 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1680,6 +1680,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			PCI device 00:14.0 write the parameter as:
 				ivrs_hpet[0]=00:14.0
 
+	ivrs_acpihid	[HW,X86_64]
+			Provide an override to the ACPI-HID:UID<->DEVICE-ID
+			mapping provided in the IVRS ACPI table. For
+			example, to map UART-HID:UID AMD0020:0 to
+			PCI device 00:14.5 write the parameter as:
+				ivrs_acpihid[00:14.5]=AMD0020:0
+
 	js=		[HW,JOY] Analog joystick
 			See Documentation/input/joystick.txt.
 
-- 
1.9.1


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

* [PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description
@ 2015-12-04  3:24   ` Wang Hongcheng
  0 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wan Zongshun

From: Wan Zongshun <Vincent.Wan@amd.com>

Add ivrs_acpihid kernel parameter description,
like ivrs_acpihid[00:14.5]=AMD0020:0.

Signed-off-by: Wan Zongshun <Vincent.Wan@amd.com>
---
 Documentation/kernel-parameters.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 742f69d..5c364c6 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1680,6 +1680,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			PCI device 00:14.0 write the parameter as:
 				ivrs_hpet[0]=00:14.0
 
+	ivrs_acpihid	[HW,X86_64]
+			Provide an override to the ACPI-HID:UID<->DEVICE-ID
+			mapping provided in the IVRS ACPI table. For
+			example, to map UART-HID:UID AMD0020:0 to
+			PCI device 00:14.5 write the parameter as:
+				ivrs_acpihid[00:14.5]=AMD0020:0
+
 	js=		[HW,JOY] Analog joystick
 			See Documentation/input/joystick.txt.
 
-- 
1.9.1


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

* [PATCH 9/9] iommu/amd: Add ACPI HID named devices IOMMU driver support
  2015-12-04  3:24 ` Wang Hongcheng
@ 2015-12-04  3:24   ` Wang Hongcheng
  -1 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wan Zongshun

From: Wan Zongshun <Vincent.Wan@amd.com>

AMD UART is a ACPI HID named device, it also is none-pci device,
currently, iommu driver only supports pci device, so UART DMA did
not work at current AMD IOMMU driver.

AMD reused 8250 serial driver and ARM PL330 DMA engine driver,
since AMD uart and dma ips are compatible with 8250 and pl330.

When those non-pci functions do DMA, they still generate some
sort of fake PCI like BDF(bus:dev:fun) id with the request to
work properly with IOMMU.

According to above descriptions, this patch was designed:

1. Add ivrs_acpihid kernel boot parameter interface, map HID:UID
to BDF id, those ids were hardcoded by AMD.
2. We never create new group for none-pci device, just adhere them
to existing group that has same bus and device id.
3. Add amd iommu callbacks for amba type bus, since pl330 driver
transferred amba_device->dev into dma_map_single.

Signed-off-by: Wan Zongshun <Vincent.Wan@amd.com>
---
 drivers/iommu/amd_iommu.c       | 165 +++++++++++++++++++++++++++++++++++-----
 drivers/iommu/amd_iommu_init.c  | 123 +++++++++++++++++++++++++++++-
 drivers/iommu/amd_iommu_types.h |  11 +++
 3 files changed, 279 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 8b2be1e..13581c0 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -35,6 +35,7 @@
 #include <linux/msi.h>
 #include <linux/dma-contiguous.h>
 #include <linux/irqdomain.h>
+#include <linux/acpi.h>
 #include <asm/irq_remapping.h>
 #include <asm/io_apic.h>
 #include <asm/apic.h>
@@ -71,6 +72,7 @@ static DEFINE_SPINLOCK(dev_data_list_lock);
 
 LIST_HEAD(ioapic_map);
 LIST_HEAD(hpet_map);
+LIST_HEAD(acpihid_map);
 
 /*
  * Domain for untranslated devices - only allocated
@@ -174,13 +176,71 @@ static struct iommu_dev_data *find_dev_data(u16 devid)
 	return dev_data;
 }
 
-static inline u16 get_device_id(struct device *dev)
+static inline int match_hid_uid(struct device *dev,
+					struct acpihid_map *entry)
+{
+	const u8 *hid, *uid;
+
+	hid = acpi_device_hid(ACPI_COMPANION(dev));
+	uid = acpi_device_uid(ACPI_COMPANION(dev));
+
+	if (!strcmp(hid, entry->hid) && !strcmp(uid, entry->uid))
+		return 0;
+
+	return -ENODEV;
+}
+
+static inline u16 get_pci_device_id(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 
 	return PCI_DEVID(pdev->bus->number, pdev->devfn);
 }
 
+static inline int get_acpihid_device_id(struct device *dev)
+{
+	struct acpihid_map *entry;
+
+	list_for_each_entry(entry, &acpihid_map, list) {
+		if (!match_hid_uid(dev, entry))
+			return entry->devid;
+	}
+	return -EINVAL;
+}
+
+static inline u16 get_device_id(struct device *dev)
+{
+	if (dev_is_pci(dev))
+		return get_pci_device_id(dev);
+	else
+		return get_acpihid_device_id(dev);
+}
+
+static void find_acpihid_group_by_rootid(struct device *dev,
+					struct iommu_group *group)
+{
+	struct acpihid_map *entry;
+
+	list_for_each_entry(entry, &acpihid_map, list) {
+		if (entry->group)
+			continue;
+		if (entry->root_devid == get_device_id(dev))
+			entry->group = group;
+	}
+}
+
+static struct iommu_group *find_acpihid_group_by_devid(struct device *dev)
+{
+	struct acpihid_map *entry;
+
+	list_for_each_entry(entry, &acpihid_map, list) {
+		if (!match_hid_uid(dev, entry))
+			return entry->group;
+	}
+
+	return NULL;
+}
+
 static struct iommu_dev_data *get_dev_data(struct device *dev)
 {
 	return dev->archdata.iommu;
@@ -260,7 +320,7 @@ static bool check_device(struct device *dev)
 		return false;
 
 	/* No PCI device */
-	if (!dev_is_pci(dev))
+	if (!dev_is_pci(dev) && (get_acpihid_device_id(dev) < 0))
 		return false;
 
 	devid = get_device_id(dev);
@@ -285,6 +345,8 @@ static void init_iommu_group(struct device *dev)
 	if (IS_ERR(group))
 		return;
 
+	find_acpihid_group_by_rootid(dev, group);
+
 	domain = iommu_group_default_domain(group);
 	if (!domain)
 		goto out;
@@ -2071,29 +2133,33 @@ static bool pci_pri_tlp_required(struct pci_dev *pdev)
 static int attach_device(struct device *dev,
 			 struct protection_domain *domain)
 {
-	struct pci_dev *pdev = to_pci_dev(dev);
 	struct iommu_dev_data *dev_data;
 	unsigned long flags;
 	int ret;
 
 	dev_data = get_dev_data(dev);
 
-	if (domain->flags & PD_IOMMUV2_MASK) {
-		if (!dev_data->passthrough)
-			return -EINVAL;
+	if (dev_is_pci(dev)) {
+
+		struct pci_dev *pdev = to_pci_dev(dev);
 
-		if (dev_data->iommu_v2) {
-			if (pdev_iommuv2_enable(pdev) != 0)
+		if (domain->flags & PD_IOMMUV2_MASK) {
+			if (!dev_data->passthrough)
 				return -EINVAL;
 
+			if (dev_data->iommu_v2) {
+				if (pdev_iommuv2_enable(pdev) != 0)
+					return -EINVAL;
+
+				dev_data->ats.enabled = true;
+				dev_data->ats.qdep    = pci_ats_queue_depth(pdev);
+				dev_data->pri_tlp     = pci_pri_tlp_required(pdev);
+			}
+		} else if (amd_iommu_iotlb_sup &&
+			   pci_enable_ats(pdev, PAGE_SHIFT) == 0) {
 			dev_data->ats.enabled = true;
 			dev_data->ats.qdep    = pci_ats_queue_depth(pdev);
-			dev_data->pri_tlp     = pci_pri_tlp_required(pdev);
 		}
-	} else if (amd_iommu_iotlb_sup &&
-		   pci_enable_ats(pdev, PAGE_SHIFT) == 0) {
-		dev_data->ats.enabled = true;
-		dev_data->ats.qdep    = pci_ats_queue_depth(pdev);
 	}
 
 	write_lock_irqsave(&amd_iommu_devtable_lock, flags);
@@ -2152,14 +2218,58 @@ static void detach_device(struct device *dev)
 	__detach_device(dev_data);
 	write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 
-	if (domain->flags & PD_IOMMUV2_MASK && dev_data->iommu_v2)
-		pdev_iommuv2_disable(to_pci_dev(dev));
-	else if (dev_data->ats.enabled)
-		pci_disable_ats(to_pci_dev(dev));
+	if (dev_is_pci(dev)) {
+
+		if (domain->flags & PD_IOMMUV2_MASK && dev_data->iommu_v2)
+			pdev_iommuv2_disable(to_pci_dev(dev));
+		else if (dev_data->ats.enabled)
+			pci_disable_ats(to_pci_dev(dev));
+	}
 
 	dev_data->ats.enabled = false;
 }
 
+static int init_acpihid_device_group(struct device *dev)
+{
+	struct dma_ops_domain *dma_domain;
+	struct iommu_dev_data *dev_data;
+	struct iommu_domain *domain;
+	struct iommu_group *group;
+	int ret;
+
+	if (dev->archdata.iommu)
+		return 0;
+
+	dev_data = find_dev_data(get_device_id(dev));
+	if (!dev_data)
+		return -ENOMEM;
+
+	dev->archdata.iommu = dev_data;
+
+	group = find_acpihid_group_by_devid(dev);
+	if (!group)
+		return -ENXIO;
+
+	ret = iommu_group_add_device(group, dev);
+	if (ret)
+		return ret;
+
+	domain = iommu_group_default_domain(group);
+	if (!domain)
+		return -ENXIO;
+
+	dma_domain = to_pdomain(domain)->priv;
+
+	init_unity_mappings_for_device(dev, dma_domain);
+
+	if (domain->type == IOMMU_DOMAIN_IDENTITY)
+		dev_data->passthrough = true;
+	else
+		dev->archdata.dma_ops = &amd_iommu_dma_ops;
+
+	return 0;
+}
+
 static int amd_iommu_add_device(struct device *dev)
 {
 	struct iommu_dev_data *dev_data;
@@ -2174,6 +2284,15 @@ static int amd_iommu_add_device(struct device *dev)
 	devid = get_device_id(dev);
 	iommu = amd_iommu_rlookup_table[devid];
 
+	if (!dev_is_pci(dev)) {
+		ret = init_acpihid_device_group(dev);
+		if (ret) {
+			iommu_ignore_device(dev);
+			dev->archdata.dma_ops = &nommu_dma_ops;
+			goto out;
+		}
+	}
+
 	ret = iommu_init_device(dev);
 	if (ret) {
 		if (ret != -ENOTSUPP)
@@ -2758,7 +2877,17 @@ static struct dma_map_ops amd_iommu_dma_ops = {
 
 int __init amd_iommu_init_api(void)
 {
-	return bus_set_iommu(&pci_bus_type, &amd_iommu_ops);
+	int err;
+
+	err = bus_set_iommu(&pci_bus_type, &amd_iommu_ops);
+	if (err)
+		return err;
+#ifdef CONFIG_ARM_AMBA
+	err = bus_set_iommu(&amba_bustype, &amd_iommu_ops);
+	if (err)
+		return err;
+#endif
+	return 0;
 }
 
 int __init amd_iommu_init_dma_ops(void)
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 013bdff..058cf5b 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -58,6 +58,7 @@
 #define IVHD_DEV_EXT_SELECT             0x46
 #define IVHD_DEV_EXT_SELECT_RANGE       0x47
 #define IVHD_DEV_SPECIAL		0x48
+#define IVHD_DEV_ACPI_HID		0xf0
 
 #define IVHD_SPECIAL_IOAPIC		1
 #define IVHD_SPECIAL_HPET		2
@@ -111,6 +112,11 @@ struct ivhd_entry {
 	u16 devid;
 	u8 flags;
 	u32 ext;
+	u32 hidh;
+	u64 cid;
+	u8 uidf;
+	u8 uidl;
+	u8 uid;
 } __attribute__((packed));
 
 /*
@@ -218,8 +224,12 @@ enum iommu_init_state {
 #define EARLY_MAP_SIZE		4
 static struct devid_map __initdata early_ioapic_map[EARLY_MAP_SIZE];
 static struct devid_map __initdata early_hpet_map[EARLY_MAP_SIZE];
+static struct acpihid_map __initdata early_acpihid_map[EARLY_MAP_SIZE];
+
 static int __initdata early_ioapic_map_size;
 static int __initdata early_hpet_map_size;
+static int __initdata early_acpihid_map_size;
+
 static bool __initdata cmdline_maps;
 
 static enum iommu_init_state init_state = IOMMU_START_STATE;
@@ -720,6 +730,45 @@ static int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line)
 	return 0;
 }
 
+static int __init add_acpi_hid_device(u8 *hid,
+			u8 *uid, u16 *devid, bool cmd_line)
+{
+	struct acpihid_map *entry;
+	struct list_head *list;
+
+	list = &acpihid_map;
+
+	list_for_each_entry(entry, list, list) {
+		if (!(!strcmp(entry->hid, hid) && !strcmp(entry->uid, uid)
+							&& entry->cmd_line))
+			continue;
+
+		pr_info("AMD-Vi: Command-line override present for hid:%s uid:%s - ignoring\n", hid, uid);
+
+		*devid = entry->devid;
+
+		return 0;
+	}
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	memcpy(entry->uid, uid, 2);
+	memcpy(entry->hid, hid, 9);
+
+	entry->devid	= *devid;
+	entry->cmd_line	= cmd_line;
+	entry->root_devid = (entry->devid & (~0x7));
+
+	pr_info("AMD-Vi:Command-line, add hid:%s,uid: %s, root_devid:%d\n",
+				entry->hid, entry->uid, entry->root_devid);
+
+	list_add_tail(&entry->list, list);
+
+	return 0;
+}
+
 static int __init add_early_maps(void)
 {
 	int i, ret;
@@ -742,6 +791,15 @@ static int __init add_early_maps(void)
 			return ret;
 	}
 
+	for (i = 0; i < early_acpihid_map_size; ++i) {
+		ret = add_acpi_hid_device(early_acpihid_map[i].hid,
+					 early_acpihid_map[i].uid,
+					 &early_acpihid_map[i].devid,
+					 early_acpihid_map[i].cmd_line);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -783,7 +841,6 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
 	struct ivhd_entry *e;
 	int ret;
 
-
 	ret = add_early_maps();
 	if (ret)
 		return ret;
@@ -799,7 +856,6 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
 	p += sizeof(struct ivhd_header);
 	end += h->length;
 
-
 	while (p < end) {
 		e = (struct ivhd_entry *)p;
 		switch (e->type) {
@@ -954,6 +1010,40 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
 
 			break;
 		}
+		case IVHD_DEV_ACPI_HID: {
+			u16 devid;
+			u8 hid[9];
+			u8 uid[2];
+			int ret;
+
+			devid  = e->devid;
+			flags = e->flags;
+
+			memcpy(hid, (u8 *)(&e->ext), 8);
+			hid[8] = '\0';
+
+			memcpy(uid, (u8 *)(&e->uid), 1);
+			uid[1] = '\0';
+
+			DUMP_printk("  DEV_ACPI_HID(%s[%s])\t\tdevid: %02x:%02x.%x\n",
+				    hid, uid,
+				    PCI_BUS_NUM(devid),
+				    PCI_SLOT(devid),
+				    PCI_FUNC(devid));
+
+			ret = add_acpi_hid_device(hid, uid, &devid, false);
+			if (ret)
+				return ret;
+
+			/*
+			 * add_special_device might update the devid in case a
+			 * command-line override is present. So call
+			 * set_dev_entry_from_acpi after add_special_device.
+			 */
+			set_dev_entry_from_acpi(iommu, devid, e->flags, 0);
+
+			break;
+		}
 		default:
 			break;
 		}
@@ -2226,10 +2316,39 @@ static int __init parse_ivrs_hpet(char *str)
 	return 1;
 }
 
+static int __init parse_ivrs_acpihid(char *str)
+{
+	u32 bus, dev, fn;
+	char *hid, *uid, *p;
+	char acpiid[11] = {0};
+	int ret, i;
+
+	ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid);
+	if (ret != 4) {
+		pr_err("AMD-Vi: Invalid command line: ivrs_acpihid(%s)\n", str);
+		return 1;
+	}
+
+	p = acpiid;
+	hid = strsep(&p, ":");
+	uid = p;
+
+	i = early_acpihid_map_size++;
+	memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
+	memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
+
+	early_acpihid_map[i].devid =
+		((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
+	early_acpihid_map[i].cmd_line	= true;
+
+	return 1;
+}
+
 __setup("amd_iommu_dump",	parse_amd_iommu_dump);
 __setup("amd_iommu=",		parse_amd_iommu_options);
 __setup("ivrs_ioapic",		parse_ivrs_ioapic);
 __setup("ivrs_hpet",		parse_ivrs_hpet);
+__setup("ivrs_acpihid",		parse_ivrs_acpihid);
 
 IOMMU_INIT_FINISH(amd_iommu_detect,
 		  gart_iommu_hole_init,
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index b08cf57..6770218 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -567,6 +567,16 @@ struct amd_iommu {
 #endif
 };
 
+struct acpihid_map {
+	struct list_head list;
+	u8 uid[2];
+	u8 hid[9];
+	u16 devid;
+	u16 root_devid;
+	bool cmd_line;
+	struct iommu_group *group;
+};
+
 struct devid_map {
 	struct list_head list;
 	u8 id;
@@ -577,6 +587,7 @@ struct devid_map {
 /* Map HPET and IOAPIC ids to the devid used by the IOMMU */
 extern struct list_head ioapic_map;
 extern struct list_head hpet_map;
+extern struct list_head acpihid_map;
 
 /*
  * List with all IOMMUs in the system. This list is not locked because it is
-- 
1.9.1


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

* [PATCH 9/9] iommu/amd: Add ACPI HID named devices IOMMU driver support
@ 2015-12-04  3:24   ` Wang Hongcheng
  0 siblings, 0 replies; 52+ messages in thread
From: Wang Hongcheng @ 2015-12-04  3:24 UTC (permalink / raw)
  To: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki
  Cc: linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li,
	Wan Zongshun

From: Wan Zongshun <Vincent.Wan@amd.com>

AMD UART is a ACPI HID named device, it also is none-pci device,
currently, iommu driver only supports pci device, so UART DMA did
not work at current AMD IOMMU driver.

AMD reused 8250 serial driver and ARM PL330 DMA engine driver,
since AMD uart and dma ips are compatible with 8250 and pl330.

When those non-pci functions do DMA, they still generate some
sort of fake PCI like BDF(bus:dev:fun) id with the request to
work properly with IOMMU.

According to above descriptions, this patch was designed:

1. Add ivrs_acpihid kernel boot parameter interface, map HID:UID
to BDF id, those ids were hardcoded by AMD.
2. We never create new group for none-pci device, just adhere them
to existing group that has same bus and device id.
3. Add amd iommu callbacks for amba type bus, since pl330 driver
transferred amba_device->dev into dma_map_single.

Signed-off-by: Wan Zongshun <Vincent.Wan@amd.com>
---
 drivers/iommu/amd_iommu.c       | 165 +++++++++++++++++++++++++++++++++++-----
 drivers/iommu/amd_iommu_init.c  | 123 +++++++++++++++++++++++++++++-
 drivers/iommu/amd_iommu_types.h |  11 +++
 3 files changed, 279 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 8b2be1e..13581c0 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -35,6 +35,7 @@
 #include <linux/msi.h>
 #include <linux/dma-contiguous.h>
 #include <linux/irqdomain.h>
+#include <linux/acpi.h>
 #include <asm/irq_remapping.h>
 #include <asm/io_apic.h>
 #include <asm/apic.h>
@@ -71,6 +72,7 @@ static DEFINE_SPINLOCK(dev_data_list_lock);
 
 LIST_HEAD(ioapic_map);
 LIST_HEAD(hpet_map);
+LIST_HEAD(acpihid_map);
 
 /*
  * Domain for untranslated devices - only allocated
@@ -174,13 +176,71 @@ static struct iommu_dev_data *find_dev_data(u16 devid)
 	return dev_data;
 }
 
-static inline u16 get_device_id(struct device *dev)
+static inline int match_hid_uid(struct device *dev,
+					struct acpihid_map *entry)
+{
+	const u8 *hid, *uid;
+
+	hid = acpi_device_hid(ACPI_COMPANION(dev));
+	uid = acpi_device_uid(ACPI_COMPANION(dev));
+
+	if (!strcmp(hid, entry->hid) && !strcmp(uid, entry->uid))
+		return 0;
+
+	return -ENODEV;
+}
+
+static inline u16 get_pci_device_id(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 
 	return PCI_DEVID(pdev->bus->number, pdev->devfn);
 }
 
+static inline int get_acpihid_device_id(struct device *dev)
+{
+	struct acpihid_map *entry;
+
+	list_for_each_entry(entry, &acpihid_map, list) {
+		if (!match_hid_uid(dev, entry))
+			return entry->devid;
+	}
+	return -EINVAL;
+}
+
+static inline u16 get_device_id(struct device *dev)
+{
+	if (dev_is_pci(dev))
+		return get_pci_device_id(dev);
+	else
+		return get_acpihid_device_id(dev);
+}
+
+static void find_acpihid_group_by_rootid(struct device *dev,
+					struct iommu_group *group)
+{
+	struct acpihid_map *entry;
+
+	list_for_each_entry(entry, &acpihid_map, list) {
+		if (entry->group)
+			continue;
+		if (entry->root_devid == get_device_id(dev))
+			entry->group = group;
+	}
+}
+
+static struct iommu_group *find_acpihid_group_by_devid(struct device *dev)
+{
+	struct acpihid_map *entry;
+
+	list_for_each_entry(entry, &acpihid_map, list) {
+		if (!match_hid_uid(dev, entry))
+			return entry->group;
+	}
+
+	return NULL;
+}
+
 static struct iommu_dev_data *get_dev_data(struct device *dev)
 {
 	return dev->archdata.iommu;
@@ -260,7 +320,7 @@ static bool check_device(struct device *dev)
 		return false;
 
 	/* No PCI device */
-	if (!dev_is_pci(dev))
+	if (!dev_is_pci(dev) && (get_acpihid_device_id(dev) < 0))
 		return false;
 
 	devid = get_device_id(dev);
@@ -285,6 +345,8 @@ static void init_iommu_group(struct device *dev)
 	if (IS_ERR(group))
 		return;
 
+	find_acpihid_group_by_rootid(dev, group);
+
 	domain = iommu_group_default_domain(group);
 	if (!domain)
 		goto out;
@@ -2071,29 +2133,33 @@ static bool pci_pri_tlp_required(struct pci_dev *pdev)
 static int attach_device(struct device *dev,
 			 struct protection_domain *domain)
 {
-	struct pci_dev *pdev = to_pci_dev(dev);
 	struct iommu_dev_data *dev_data;
 	unsigned long flags;
 	int ret;
 
 	dev_data = get_dev_data(dev);
 
-	if (domain->flags & PD_IOMMUV2_MASK) {
-		if (!dev_data->passthrough)
-			return -EINVAL;
+	if (dev_is_pci(dev)) {
+
+		struct pci_dev *pdev = to_pci_dev(dev);
 
-		if (dev_data->iommu_v2) {
-			if (pdev_iommuv2_enable(pdev) != 0)
+		if (domain->flags & PD_IOMMUV2_MASK) {
+			if (!dev_data->passthrough)
 				return -EINVAL;
 
+			if (dev_data->iommu_v2) {
+				if (pdev_iommuv2_enable(pdev) != 0)
+					return -EINVAL;
+
+				dev_data->ats.enabled = true;
+				dev_data->ats.qdep    = pci_ats_queue_depth(pdev);
+				dev_data->pri_tlp     = pci_pri_tlp_required(pdev);
+			}
+		} else if (amd_iommu_iotlb_sup &&
+			   pci_enable_ats(pdev, PAGE_SHIFT) == 0) {
 			dev_data->ats.enabled = true;
 			dev_data->ats.qdep    = pci_ats_queue_depth(pdev);
-			dev_data->pri_tlp     = pci_pri_tlp_required(pdev);
 		}
-	} else if (amd_iommu_iotlb_sup &&
-		   pci_enable_ats(pdev, PAGE_SHIFT) == 0) {
-		dev_data->ats.enabled = true;
-		dev_data->ats.qdep    = pci_ats_queue_depth(pdev);
 	}
 
 	write_lock_irqsave(&amd_iommu_devtable_lock, flags);
@@ -2152,14 +2218,58 @@ static void detach_device(struct device *dev)
 	__detach_device(dev_data);
 	write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 
-	if (domain->flags & PD_IOMMUV2_MASK && dev_data->iommu_v2)
-		pdev_iommuv2_disable(to_pci_dev(dev));
-	else if (dev_data->ats.enabled)
-		pci_disable_ats(to_pci_dev(dev));
+	if (dev_is_pci(dev)) {
+
+		if (domain->flags & PD_IOMMUV2_MASK && dev_data->iommu_v2)
+			pdev_iommuv2_disable(to_pci_dev(dev));
+		else if (dev_data->ats.enabled)
+			pci_disable_ats(to_pci_dev(dev));
+	}
 
 	dev_data->ats.enabled = false;
 }
 
+static int init_acpihid_device_group(struct device *dev)
+{
+	struct dma_ops_domain *dma_domain;
+	struct iommu_dev_data *dev_data;
+	struct iommu_domain *domain;
+	struct iommu_group *group;
+	int ret;
+
+	if (dev->archdata.iommu)
+		return 0;
+
+	dev_data = find_dev_data(get_device_id(dev));
+	if (!dev_data)
+		return -ENOMEM;
+
+	dev->archdata.iommu = dev_data;
+
+	group = find_acpihid_group_by_devid(dev);
+	if (!group)
+		return -ENXIO;
+
+	ret = iommu_group_add_device(group, dev);
+	if (ret)
+		return ret;
+
+	domain = iommu_group_default_domain(group);
+	if (!domain)
+		return -ENXIO;
+
+	dma_domain = to_pdomain(domain)->priv;
+
+	init_unity_mappings_for_device(dev, dma_domain);
+
+	if (domain->type == IOMMU_DOMAIN_IDENTITY)
+		dev_data->passthrough = true;
+	else
+		dev->archdata.dma_ops = &amd_iommu_dma_ops;
+
+	return 0;
+}
+
 static int amd_iommu_add_device(struct device *dev)
 {
 	struct iommu_dev_data *dev_data;
@@ -2174,6 +2284,15 @@ static int amd_iommu_add_device(struct device *dev)
 	devid = get_device_id(dev);
 	iommu = amd_iommu_rlookup_table[devid];
 
+	if (!dev_is_pci(dev)) {
+		ret = init_acpihid_device_group(dev);
+		if (ret) {
+			iommu_ignore_device(dev);
+			dev->archdata.dma_ops = &nommu_dma_ops;
+			goto out;
+		}
+	}
+
 	ret = iommu_init_device(dev);
 	if (ret) {
 		if (ret != -ENOTSUPP)
@@ -2758,7 +2877,17 @@ static struct dma_map_ops amd_iommu_dma_ops = {
 
 int __init amd_iommu_init_api(void)
 {
-	return bus_set_iommu(&pci_bus_type, &amd_iommu_ops);
+	int err;
+
+	err = bus_set_iommu(&pci_bus_type, &amd_iommu_ops);
+	if (err)
+		return err;
+#ifdef CONFIG_ARM_AMBA
+	err = bus_set_iommu(&amba_bustype, &amd_iommu_ops);
+	if (err)
+		return err;
+#endif
+	return 0;
 }
 
 int __init amd_iommu_init_dma_ops(void)
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 013bdff..058cf5b 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -58,6 +58,7 @@
 #define IVHD_DEV_EXT_SELECT             0x46
 #define IVHD_DEV_EXT_SELECT_RANGE       0x47
 #define IVHD_DEV_SPECIAL		0x48
+#define IVHD_DEV_ACPI_HID		0xf0
 
 #define IVHD_SPECIAL_IOAPIC		1
 #define IVHD_SPECIAL_HPET		2
@@ -111,6 +112,11 @@ struct ivhd_entry {
 	u16 devid;
 	u8 flags;
 	u32 ext;
+	u32 hidh;
+	u64 cid;
+	u8 uidf;
+	u8 uidl;
+	u8 uid;
 } __attribute__((packed));
 
 /*
@@ -218,8 +224,12 @@ enum iommu_init_state {
 #define EARLY_MAP_SIZE		4
 static struct devid_map __initdata early_ioapic_map[EARLY_MAP_SIZE];
 static struct devid_map __initdata early_hpet_map[EARLY_MAP_SIZE];
+static struct acpihid_map __initdata early_acpihid_map[EARLY_MAP_SIZE];
+
 static int __initdata early_ioapic_map_size;
 static int __initdata early_hpet_map_size;
+static int __initdata early_acpihid_map_size;
+
 static bool __initdata cmdline_maps;
 
 static enum iommu_init_state init_state = IOMMU_START_STATE;
@@ -720,6 +730,45 @@ static int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line)
 	return 0;
 }
 
+static int __init add_acpi_hid_device(u8 *hid,
+			u8 *uid, u16 *devid, bool cmd_line)
+{
+	struct acpihid_map *entry;
+	struct list_head *list;
+
+	list = &acpihid_map;
+
+	list_for_each_entry(entry, list, list) {
+		if (!(!strcmp(entry->hid, hid) && !strcmp(entry->uid, uid)
+							&& entry->cmd_line))
+			continue;
+
+		pr_info("AMD-Vi: Command-line override present for hid:%s uid:%s - ignoring\n", hid, uid);
+
+		*devid = entry->devid;
+
+		return 0;
+	}
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	memcpy(entry->uid, uid, 2);
+	memcpy(entry->hid, hid, 9);
+
+	entry->devid	= *devid;
+	entry->cmd_line	= cmd_line;
+	entry->root_devid = (entry->devid & (~0x7));
+
+	pr_info("AMD-Vi:Command-line, add hid:%s,uid: %s, root_devid:%d\n",
+				entry->hid, entry->uid, entry->root_devid);
+
+	list_add_tail(&entry->list, list);
+
+	return 0;
+}
+
 static int __init add_early_maps(void)
 {
 	int i, ret;
@@ -742,6 +791,15 @@ static int __init add_early_maps(void)
 			return ret;
 	}
 
+	for (i = 0; i < early_acpihid_map_size; ++i) {
+		ret = add_acpi_hid_device(early_acpihid_map[i].hid,
+					 early_acpihid_map[i].uid,
+					 &early_acpihid_map[i].devid,
+					 early_acpihid_map[i].cmd_line);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -783,7 +841,6 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
 	struct ivhd_entry *e;
 	int ret;
 
-
 	ret = add_early_maps();
 	if (ret)
 		return ret;
@@ -799,7 +856,6 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
 	p += sizeof(struct ivhd_header);
 	end += h->length;
 
-
 	while (p < end) {
 		e = (struct ivhd_entry *)p;
 		switch (e->type) {
@@ -954,6 +1010,40 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
 
 			break;
 		}
+		case IVHD_DEV_ACPI_HID: {
+			u16 devid;
+			u8 hid[9];
+			u8 uid[2];
+			int ret;
+
+			devid  = e->devid;
+			flags = e->flags;
+
+			memcpy(hid, (u8 *)(&e->ext), 8);
+			hid[8] = '\0';
+
+			memcpy(uid, (u8 *)(&e->uid), 1);
+			uid[1] = '\0';
+
+			DUMP_printk("  DEV_ACPI_HID(%s[%s])\t\tdevid: %02x:%02x.%x\n",
+				    hid, uid,
+				    PCI_BUS_NUM(devid),
+				    PCI_SLOT(devid),
+				    PCI_FUNC(devid));
+
+			ret = add_acpi_hid_device(hid, uid, &devid, false);
+			if (ret)
+				return ret;
+
+			/*
+			 * add_special_device might update the devid in case a
+			 * command-line override is present. So call
+			 * set_dev_entry_from_acpi after add_special_device.
+			 */
+			set_dev_entry_from_acpi(iommu, devid, e->flags, 0);
+
+			break;
+		}
 		default:
 			break;
 		}
@@ -2226,10 +2316,39 @@ static int __init parse_ivrs_hpet(char *str)
 	return 1;
 }
 
+static int __init parse_ivrs_acpihid(char *str)
+{
+	u32 bus, dev, fn;
+	char *hid, *uid, *p;
+	char acpiid[11] = {0};
+	int ret, i;
+
+	ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid);
+	if (ret != 4) {
+		pr_err("AMD-Vi: Invalid command line: ivrs_acpihid(%s)\n", str);
+		return 1;
+	}
+
+	p = acpiid;
+	hid = strsep(&p, ":");
+	uid = p;
+
+	i = early_acpihid_map_size++;
+	memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
+	memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
+
+	early_acpihid_map[i].devid =
+		((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
+	early_acpihid_map[i].cmd_line	= true;
+
+	return 1;
+}
+
 __setup("amd_iommu_dump",	parse_amd_iommu_dump);
 __setup("amd_iommu=",		parse_amd_iommu_options);
 __setup("ivrs_ioapic",		parse_ivrs_ioapic);
 __setup("ivrs_hpet",		parse_ivrs_hpet);
+__setup("ivrs_acpihid",		parse_ivrs_acpihid);
 
 IOMMU_INIT_FINISH(amd_iommu_detect,
 		  gart_iommu_hole_init,
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index b08cf57..6770218 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -567,6 +567,16 @@ struct amd_iommu {
 #endif
 };
 
+struct acpihid_map {
+	struct list_head list;
+	u8 uid[2];
+	u8 hid[9];
+	u16 devid;
+	u16 root_devid;
+	bool cmd_line;
+	struct iommu_group *group;
+};
+
 struct devid_map {
 	struct list_head list;
 	u8 id;
@@ -577,6 +587,7 @@ struct devid_map {
 /* Map HPET and IOAPIC ids to the devid used by the IOMMU */
 extern struct list_head ioapic_map;
 extern struct list_head hpet_map;
+extern struct list_head acpihid_map;
 
 /*
  * List with all IOMMUs in the system. This list is not locked because it is
-- 
1.9.1


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

* Re: [PATCH 1/9] ACPI: Add support for AMBA bus type
  2015-12-04  3:24   ` Wang Hongcheng
  (?)
@ 2015-12-04  8:50   ` Mika Westerberg
  2015-12-04  9:17       ` Huang Rui
  -1 siblings, 1 reply; 52+ messages in thread
From: Mika Westerberg @ 2015-12-04  8:50 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: Vinod Koul, Joerg Roedel, Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-acpi, linux-kernel, linux-serial, dmaengine, iommu,
	Borislav Petkov, Huang Rui, Wan Zongshun, Ken Xue, Tony Li

On Fri, Dec 04, 2015 at 11:24:18AM +0800, Wang Hongcheng wrote:
> From: Huang Rui <ray.huang@amd.com>
> 
> Inspired by acpi platform bus type, to make driver "porting" more
> straightforward, this patch introduces ACPI support to the AMBA bus
> type. Instead of writing ACPI "glue" drivers for the exiting AMBA
> drivers.

Hmm, isn't there already similar patch series bringing AMBA ACPI
support?

https://lkml.org/lkml/2015/9/30/394

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

* Re: [PATCH 1/9] ACPI: Add support for AMBA bus type
  2015-12-04  8:50   ` Mika Westerberg
@ 2015-12-04  9:17       ` Huang Rui
  0 siblings, 0 replies; 52+ messages in thread
From: Huang Rui @ 2015-12-04  9:17 UTC (permalink / raw)
  To: Mika Westerberg, Graeme Gregory
  Cc: Wang Hongcheng, Vinod Koul, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Wan Zongshun, Ken Xue,
	Tony Li

On Fri, Dec 04, 2015 at 10:50:23AM +0200, Mika Westerberg wrote:
> On Fri, Dec 04, 2015 at 11:24:18AM +0800, Wang Hongcheng wrote:
> > From: Huang Rui <ray.huang@amd.com>
> > 
> > Inspired by acpi platform bus type, to make driver "porting" more
> > straightforward, this patch introduces ACPI support to the AMBA bus
> > type. Instead of writing ACPI "glue" drivers for the exiting AMBA
> > drivers.
> 
> Hmm, isn't there already similar patch series bringing AMBA ACPI
> support?
> 
> https://lkml.org/lkml/2015/9/30/394

Err, I see the patch for the first time...

But looks like it isn't accepted till now. Will he continue to work on
it?

Thanks,
Rui

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

* Re: [PATCH 1/9] ACPI: Add support for AMBA bus type
@ 2015-12-04  9:17       ` Huang Rui
  0 siblings, 0 replies; 52+ messages in thread
From: Huang Rui @ 2015-12-04  9:17 UTC (permalink / raw)
  To: Mika Westerberg, Graeme Gregory
  Cc: Wang Hongcheng, Vinod Koul, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Wan Zongshun, Ken Xue,
	Tony Li

On Fri, Dec 04, 2015 at 10:50:23AM +0200, Mika Westerberg wrote:
> On Fri, Dec 04, 2015 at 11:24:18AM +0800, Wang Hongcheng wrote:
> > From: Huang Rui <ray.huang@amd.com>
> > 
> > Inspired by acpi platform bus type, to make driver "porting" more
> > straightforward, this patch introduces ACPI support to the AMBA bus
> > type. Instead of writing ACPI "glue" drivers for the exiting AMBA
> > drivers.
> 
> Hmm, isn't there already similar patch series bringing AMBA ACPI
> support?
> 
> https://lkml.org/lkml/2015/9/30/394

Err, I see the patch for the first time...

But looks like it isn't accepted till now. Will he continue to work on
it?

Thanks,
Rui

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

* Re: [PATCH 1/9] ACPI: Add support for AMBA bus type
  2015-12-04  9:17       ` Huang Rui
@ 2015-12-04  9:42         ` Hanjun Guo
  -1 siblings, 0 replies; 52+ messages in thread
From: Hanjun Guo @ 2015-12-04  9:42 UTC (permalink / raw)
  To: Huang Rui, Mika Westerberg, Graeme Gregory
  Cc: Wang Hongcheng, Vinod Koul, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Wan Zongshun, Ken Xue,
	Tony Li

On 2015/12/4 17:17, Huang Rui wrote:
> On Fri, Dec 04, 2015 at 10:50:23AM +0200, Mika Westerberg wrote:
>> On Fri, Dec 04, 2015 at 11:24:18AM +0800, Wang Hongcheng wrote:
>>> From: Huang Rui <ray.huang@amd.com>
>>>
>>> Inspired by acpi platform bus type, to make driver "porting" more
>>> straightforward, this patch introduces ACPI support to the AMBA bus
>>> type. Instead of writing ACPI "glue" drivers for the exiting AMBA
>>> drivers.
>> Hmm, isn't there already similar patch series bringing AMBA ACPI
>> support?
>>
>> https://lkml.org/lkml/2015/9/30/394
> Err, I see the patch for the first time...
>
> But looks like it isn't accepted till now. Will he continue to work on
> it?

Sure, Graeme is working on the updated version now :)

Thanks
Hanjun


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

* Re: [PATCH 1/9] ACPI: Add support for AMBA bus type
@ 2015-12-04  9:42         ` Hanjun Guo
  0 siblings, 0 replies; 52+ messages in thread
From: Hanjun Guo @ 2015-12-04  9:42 UTC (permalink / raw)
  To: Huang Rui, Mika Westerberg, Graeme Gregory
  Cc: Wang Hongcheng, Vinod Koul, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Wan Zongshun, Ken Xue,
	Tony Li

On 2015/12/4 17:17, Huang Rui wrote:
> On Fri, Dec 04, 2015 at 10:50:23AM +0200, Mika Westerberg wrote:
>> On Fri, Dec 04, 2015 at 11:24:18AM +0800, Wang Hongcheng wrote:
>>> From: Huang Rui <ray.huang@amd.com>
>>>
>>> Inspired by acpi platform bus type, to make driver "porting" more
>>> straightforward, this patch introduces ACPI support to the AMBA bus
>>> type. Instead of writing ACPI "glue" drivers for the exiting AMBA
>>> drivers.
>> Hmm, isn't there already similar patch series bringing AMBA ACPI
>> support?
>>
>> https://lkml.org/lkml/2015/9/30/394
> Err, I see the patch for the first time...
>
> But looks like it isn't accepted till now. Will he continue to work on
> it?

Sure, Graeme is working on the updated version now :)

Thanks
Hanjun


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

* Re: [PATCH 1/9] ACPI: Add support for AMBA bus type
  2015-12-04  9:42         ` Hanjun Guo
  (?)
@ 2015-12-04  9:59         ` G Gregory
  2015-12-04 10:20             ` Huang Rui
  -1 siblings, 1 reply; 52+ messages in thread
From: G Gregory @ 2015-12-04  9:59 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Huang Rui, Mika Westerberg, Wang Hongcheng, Vinod Koul,
	Joerg Roedel, Greg Kroah-Hartman, Rafael J. Wysocki, linux-acpi,
	linux-kernel, linux-serial, dmaengine, iommu, Borislav Petkov,
	Wan Zongshun, Ken Xue, Tony Li

On 4 December 2015 at 09:42, Hanjun Guo <guohanjun@huawei.com> wrote:
> On 2015/12/4 17:17, Huang Rui wrote:
>> On Fri, Dec 04, 2015 at 10:50:23AM +0200, Mika Westerberg wrote:
>>> On Fri, Dec 04, 2015 at 11:24:18AM +0800, Wang Hongcheng wrote:
>>>> From: Huang Rui <ray.huang@amd.com>
>>>>
>>>> Inspired by acpi platform bus type, to make driver "porting" more
>>>> straightforward, this patch introduces ACPI support to the AMBA bus
>>>> type. Instead of writing ACPI "glue" drivers for the exiting AMBA
>>>> drivers.
>>> Hmm, isn't there already similar patch series bringing AMBA ACPI
>>> support?
>>>
>>> https://lkml.org/lkml/2015/9/30/394
>> Err, I see the patch for the first time...
>>
>> But looks like it isn't accepted till now. Will he continue to work on
>> it?
>
> Sure, Graeme is working on the updated version now :)
>
Yes, as Hanjun said I am planning a v2. I've just been caught up in
other business this week and probably next week.

Graeme

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

* Re: [PATCH 1/9] ACPI: Add support for AMBA bus type
  2015-12-04  9:59         ` G Gregory
@ 2015-12-04 10:20             ` Huang Rui
  0 siblings, 0 replies; 52+ messages in thread
From: Huang Rui @ 2015-12-04 10:20 UTC (permalink / raw)
  To: G Gregory
  Cc: Hanjun Guo, Mika Westerberg, Wang Hongcheng, Vinod Koul,
	Joerg Roedel, Greg Kroah-Hartman, Rafael J. Wysocki, linux-acpi,
	linux-kernel, linux-serial, dmaengine, iommu, Borislav Petkov,
	Wan Zongshun, Ken Xue, Tony Li

On Fri, Dec 04, 2015 at 09:59:28AM +0000, G Gregory wrote:
> On 4 December 2015 at 09:42, Hanjun Guo <guohanjun@huawei.com> wrote:
> > On 2015/12/4 17:17, Huang Rui wrote:
> >> On Fri, Dec 04, 2015 at 10:50:23AM +0200, Mika Westerberg wrote:
> >>> On Fri, Dec 04, 2015 at 11:24:18AM +0800, Wang Hongcheng wrote:
> >>>> From: Huang Rui <ray.huang@amd.com>
> >>>>
> >>>> Inspired by acpi platform bus type, to make driver "porting" more
> >>>> straightforward, this patch introduces ACPI support to the AMBA bus
> >>>> type. Instead of writing ACPI "glue" drivers for the exiting AMBA
> >>>> drivers.
> >>> Hmm, isn't there already similar patch series bringing AMBA ACPI
> >>> support?
> >>>
> >>> https://lkml.org/lkml/2015/9/30/394
> >> Err, I see the patch for the first time...
> >>
> >> But looks like it isn't accepted till now. Will he continue to work on
> >> it?
> >
> > Sure, Graeme is working on the updated version now :)
> >
> Yes, as Hanjun said I am planning a v2. I've just been caught up in
> other business this week and probably next week.
> 

OK, thanks to clarify it. Could you please take care of AMD use case
that we need a configurable fix_rate clk, periphid, and platform data?

Thanks,
Rui

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

* Re: [PATCH 1/9] ACPI: Add support for AMBA bus type
@ 2015-12-04 10:20             ` Huang Rui
  0 siblings, 0 replies; 52+ messages in thread
From: Huang Rui @ 2015-12-04 10:20 UTC (permalink / raw)
  To: G Gregory
  Cc: Hanjun Guo, Mika Westerberg, Wang Hongcheng, Vinod Koul,
	Joerg Roedel, Greg Kroah-Hartman, Rafael J. Wysocki, linux-acpi,
	linux-kernel, linux-serial, dmaengine, iommu, Borislav Petkov,
	Wan Zongshun, Ken Xue, Tony Li

On Fri, Dec 04, 2015 at 09:59:28AM +0000, G Gregory wrote:
> On 4 December 2015 at 09:42, Hanjun Guo <guohanjun@huawei.com> wrote:
> > On 2015/12/4 17:17, Huang Rui wrote:
> >> On Fri, Dec 04, 2015 at 10:50:23AM +0200, Mika Westerberg wrote:
> >>> On Fri, Dec 04, 2015 at 11:24:18AM +0800, Wang Hongcheng wrote:
> >>>> From: Huang Rui <ray.huang@amd.com>
> >>>>
> >>>> Inspired by acpi platform bus type, to make driver "porting" more
> >>>> straightforward, this patch introduces ACPI support to the AMBA bus
> >>>> type. Instead of writing ACPI "glue" drivers for the exiting AMBA
> >>>> drivers.
> >>> Hmm, isn't there already similar patch series bringing AMBA ACPI
> >>> support?
> >>>
> >>> https://lkml.org/lkml/2015/9/30/394
> >> Err, I see the patch for the first time...
> >>
> >> But looks like it isn't accepted till now. Will he continue to work on
> >> it?
> >
> > Sure, Graeme is working on the updated version now :)
> >
> Yes, as Hanjun said I am planning a v2. I've just been caught up in
> other business this week and probably next week.
> 

OK, thanks to clarify it. Could you please take care of AMD use case
that we need a configurable fix_rate clk, periphid, and platform data?

Thanks,
Rui

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

* Re: [PATCH 1/9] ACPI: Add support for AMBA bus type
  2015-12-04 10:20             ` Huang Rui
  (?)
@ 2015-12-04 10:23             ` G Gregory
  -1 siblings, 0 replies; 52+ messages in thread
From: G Gregory @ 2015-12-04 10:23 UTC (permalink / raw)
  To: Huang Rui
  Cc: Hanjun Guo, Mika Westerberg, Wang Hongcheng, Vinod Koul,
	Joerg Roedel, Greg Kroah-Hartman, Rafael J. Wysocki, linux-acpi,
	linux-kernel, linux-serial, dmaengine, iommu, Borislav Petkov,
	Wan Zongshun, Ken Xue, Tony Li

On 4 December 2015 at 10:20, Huang Rui <ray.huang@amd.com> wrote:
> On Fri, Dec 04, 2015 at 09:59:28AM +0000, G Gregory wrote:
>> On 4 December 2015 at 09:42, Hanjun Guo <guohanjun@huawei.com> wrote:
>> > On 2015/12/4 17:17, Huang Rui wrote:
>> >> On Fri, Dec 04, 2015 at 10:50:23AM +0200, Mika Westerberg wrote:
>> >>> On Fri, Dec 04, 2015 at 11:24:18AM +0800, Wang Hongcheng wrote:
>> >>>> From: Huang Rui <ray.huang@amd.com>
>> >>>>
>> >>>> Inspired by acpi platform bus type, to make driver "porting" more
>> >>>> straightforward, this patch introduces ACPI support to the AMBA bus
>> >>>> type. Instead of writing ACPI "glue" drivers for the exiting AMBA
>> >>>> drivers.
>> >>> Hmm, isn't there already similar patch series bringing AMBA ACPI
>> >>> support?
>> >>>
>> >>> https://lkml.org/lkml/2015/9/30/394
>> >> Err, I see the patch for the first time...
>> >>
>> >> But looks like it isn't accepted till now. Will he continue to work on
>> >> it?
>> >
>> > Sure, Graeme is working on the updated version now :)
>> >
>> Yes, as Hanjun said I am planning a v2. I've just been caught up in
>> other business this week and probably next week.
>>
>
> OK, thanks to clarify it. Could you please take care of AMD use case
> that we need a configurable fix_rate clk, periphid, and platform data?
>
I will take a look at your patch in detail when I redo my series.

Thanks

Graeme

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

* Re: [PATCH 2/9] 8250/Kconfig: add config option CONFIG_SERIAL_8250_AMD
  2015-12-04  3:24   ` Wang Hongcheng
  (?)
@ 2015-12-04 11:11   ` Borislav Petkov
  -1 siblings, 0 replies; 52+ messages in thread
From: Borislav Petkov @ 2015-12-04 11:11 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Huang Rui, Wan Zongshun, Ken Xue, Tony Li

On Fri, Dec 04, 2015 at 11:24:19AM +0800, Wang Hongcheng wrote:
> Add config option  CONFIG_SERIAL_8250_AMD in use of AMD carrizo.
> Because carrizo's UART DMA device is an amba device, it selects
> ARM_AMBA option. Anything uses amba devices must select ARM_AMBA.
> 
> Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
> ---
>  drivers/tty/serial/8250/Kconfig | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
> index 6412f14..d9717c1 100644
> --- a/drivers/tty/serial/8250/Kconfig
> +++ b/drivers/tty/serial/8250/Kconfig
> @@ -378,3 +378,11 @@ config SERIAL_8250_MID
>  	  Selecting this option will enable handling of the extra features
>  	  present on the UART found on Intel Medfield SOC and various other
>  	  Intel platforms.
> +
> +config SERIAL_8250_AMD
> +        bool "AMD carrizo serial port support"
> +        depends on SERIAL_8250
> +	select ARM_AMBA
> +        help
> +           If you have a Carrizo  based board and want to use the
> +           serial port, say Y to this option. If unsure, say N.

Please do not use "Carrizo" in any user-visible text because the vendors
and their marketing departments naming are confusing us to hell already.
Use F15h, models 0x60-0x6F (I believe CZ is this range but I'm not sure
myself anymore either) so that people *actually* can know what kind of
CPU it is by looking at /proc/cpuinfo.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

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

* Re: [PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description
  2015-12-04  3:24   ` Wang Hongcheng
@ 2015-12-04 12:21       ` Borislav Petkov
  -1 siblings, 0 replies; 52+ messages in thread
From: Borislav Petkov @ 2015-12-04 12:21 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: Tony Li, Wan Zongshun, Vinod Koul, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Huang Rui,
	linux-serial-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, Mika Westerberg, Ken Xue

On Fri, Dec 04, 2015 at 11:24:25AM +0800, Wang Hongcheng wrote:
> From: Wan Zongshun <Vincent.Wan-5C7GfCeVMHo@public.gmane.org>
> 
> Add ivrs_acpihid kernel parameter description,
> like ivrs_acpihid[00:14.5]=AMD0020:0.
> 
> Signed-off-by: Wan Zongshun <Vincent.Wan-5C7GfCeVMHo@public.gmane.org>
> ---
>  Documentation/kernel-parameters.txt | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 742f69d..5c364c6 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -1680,6 +1680,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>  			PCI device 00:14.0 write the parameter as:
>  				ivrs_hpet[0]=00:14.0
>  
> +	ivrs_acpihid	[HW,X86_64]
> +			Provide an override to the ACPI-HID:UID<->DEVICE-ID
> +			mapping provided in the IVRS ACPI table. For
> +			example, to map UART-HID:UID AMD0020:0 to
> +			PCI device 00:14.5 write the parameter as:
> +				ivrs_acpihid[00:14.5]=AMD0020:0

What is that parameter needed for? Can't you deduce the mapping from the
hardware?

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

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

* Re: [PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description
@ 2015-12-04 12:21       ` Borislav Petkov
  0 siblings, 0 replies; 52+ messages in thread
From: Borislav Petkov @ 2015-12-04 12:21 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Huang Rui, Wan Zongshun, Ken Xue, Tony Li

On Fri, Dec 04, 2015 at 11:24:25AM +0800, Wang Hongcheng wrote:
> From: Wan Zongshun <Vincent.Wan@amd.com>
> 
> Add ivrs_acpihid kernel parameter description,
> like ivrs_acpihid[00:14.5]=AMD0020:0.
> 
> Signed-off-by: Wan Zongshun <Vincent.Wan@amd.com>
> ---
>  Documentation/kernel-parameters.txt | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 742f69d..5c364c6 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -1680,6 +1680,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>  			PCI device 00:14.0 write the parameter as:
>  				ivrs_hpet[0]=00:14.0
>  
> +	ivrs_acpihid	[HW,X86_64]
> +			Provide an override to the ACPI-HID:UID<->DEVICE-ID
> +			mapping provided in the IVRS ACPI table. For
> +			example, to map UART-HID:UID AMD0020:0 to
> +			PCI device 00:14.5 write the parameter as:
> +				ivrs_acpihid[00:14.5]=AMD0020:0

What is that parameter needed for? Can't you deduce the mapping from the
hardware?

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

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

* Re: [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config
  2015-12-04  3:24   ` Wang Hongcheng
@ 2015-12-04 12:56       ` kbuild test robot
  -1 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2015-12-04 12:56 UTC (permalink / raw)
  Cc: Tony Li, Wan Zongshun, Vinod Koul, Greg Kroah-Hartman,
	Wang Hongcheng, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Huang Rui,
	Borislav Petkov, kbuild-all-JC7UmRfGjtg,
	linux-serial-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, Mika Westerberg, Ken Xue

[-- Attachment #1: Type: text/plain, Size: 1352 bytes --]

Hi Wang,

[auto build test ERROR on pm/linux-next]
[also build test ERROR on v4.4-rc3 next-20151203]

url:    https://github.com/0day-ci/linux/commits/Wang-Hongcheng/8250-AMD-Carrizo-UART-PL300-DMA-enablement/20151204-203235
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
config: x86_64-lkp (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/acpi/acpi_apd.c: In function 'acpi_apd_create_device':
>> drivers/acpi/acpi_apd.c:145:3: error: implicit declaration of function 'setup_quirks' [-Werror=implicit-function-declaration]
      setup_quirks(pdev, &amba_quirks);
      ^
   cc1: some warnings being treated as errors

vim +/setup_quirks +145 drivers/acpi/acpi_apd.c

   139		pdev = acpi_create_platform_device(adev);
   140		if (IS_ERR_OR_NULL(pdev))
   141			goto err_out;
   142	
   143		if (!strncmp(pdev->name, "AMD0020", 7)) {
   144			memset(&amba_quirks, 0, sizeof(amba_quirks));
 > 145			setup_quirks(pdev, &amba_quirks);
   146	
   147			amba_dev = acpi_create_amba_device(pdata->adev, 0x00041330,
   148							   48000000,

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 22105 bytes --]

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



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

* Re: [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config
@ 2015-12-04 12:56       ` kbuild test robot
  0 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2015-12-04 12:56 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: kbuild-all, Vinod Koul, Mika Westerberg, Joerg Roedel,
	Greg Kroah-Hartman, Rafael J. Wysocki, linux-acpi, linux-kernel,
	linux-serial, dmaengine, iommu, Borislav Petkov, Huang Rui,
	Wan Zongshun, Ken Xue, Tony Li, Wang Hongcheng

[-- Attachment #1: Type: text/plain, Size: 1352 bytes --]

Hi Wang,

[auto build test ERROR on pm/linux-next]
[also build test ERROR on v4.4-rc3 next-20151203]

url:    https://github.com/0day-ci/linux/commits/Wang-Hongcheng/8250-AMD-Carrizo-UART-PL300-DMA-enablement/20151204-203235
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
config: x86_64-lkp (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/acpi/acpi_apd.c: In function 'acpi_apd_create_device':
>> drivers/acpi/acpi_apd.c:145:3: error: implicit declaration of function 'setup_quirks' [-Werror=implicit-function-declaration]
      setup_quirks(pdev, &amba_quirks);
      ^
   cc1: some warnings being treated as errors

vim +/setup_quirks +145 drivers/acpi/acpi_apd.c

   139		pdev = acpi_create_platform_device(adev);
   140		if (IS_ERR_OR_NULL(pdev))
   141			goto err_out;
   142	
   143		if (!strncmp(pdev->name, "AMD0020", 7)) {
   144			memset(&amba_quirks, 0, sizeof(amba_quirks));
 > 145			setup_quirks(pdev, &amba_quirks);
   146	
   147			amba_dev = acpi_create_amba_device(pdata->adev, 0x00041330,
   148							   48000000,

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 22105 bytes --]

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

* Re: [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config
  2015-12-04  3:24   ` Wang Hongcheng
  (?)
  (?)
@ 2015-12-04 13:16   ` Graeme Gregory
  2015-12-11  6:57     ` Wang, Annie
  -1 siblings, 1 reply; 52+ messages in thread
From: Graeme Gregory @ 2015-12-04 13:16 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Huang Rui, Wan Zongshun,
	Ken Xue, Tony Li

On Fri, Dec 04, 2015 at 11:24:20AM +0800, Wang Hongcheng wrote:
> AMD pl330 is a UART DMA device, it shares one ACPI item with UART. So
> a platform device and an acpi device will be created according to
> AMD0020 ACPI dev. And its mem base address must have an offset. As a
> result, MULTI_ATTACHED_QUIRK and MULTI_ATTACHED_QUIRK are used.
> 
> Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
> ---
>  drivers/acpi/acpi_amba.c | 31 +++++++++++++++++++++++----
>  drivers/acpi/acpi_apd.c  | 56 +++++++++++++++++++++++++++++++++++++-----------
>  include/linux/acpi.h     | 13 +++++++++--
>  3 files changed, 81 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
> index 4f0366a..8a5269c 100644
> --- a/drivers/acpi/acpi_amba.c
> +++ b/drivers/acpi/acpi_amba.c
> @@ -31,6 +31,8 @@ ACPI_MODULE_NAME("amba");
>   * @periphid: AMBA device periphid.
>   * @fixed_rate: Clock frequency.
>   * @pdata: Platform data specific to the device.
> + * @quirk: Specific device config, including device multiattach.
> + * and mem base offset.
>   *
>   * Check if the given @adev can be represented as an AMBA device and, if
>   * that's the case, create and register an AMBA device, populate its
> @@ -42,7 +44,8 @@ ACPI_MODULE_NAME("amba");
>  struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
>  					    unsigned int periphid,
>  					    unsigned long fixed_rate,
> -					    void *pdata)
> +					    void *pdata,
> +					    struct acpi_amba_quirk *quirk)
>  {
>  	struct amba_device *amba_dev = NULL;
>  	struct device *parent;
> @@ -54,12 +57,14 @@ struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
>  	unsigned int i;
>  	unsigned int irq[AMBA_NR_IRQS];
>  	struct clk *clk = ERR_PTR(-ENODEV);
> +	char amba_devname[100];
>  
>  	/*
>  	 * If the ACPI node already has a physical device attached,
> -	 * skip it.
> +	 * skip it. Except some special devices such as AMD0020 which
> +	 * needs attach physical devices two times.
>  	 */
> -	if (adev->physical_node_count)
> +	if (adev->physical_node_count && !(quirk->quirk & MULTI_ATTACHED_QUIRK))
>  		return NULL;
>  
>  	INIT_LIST_HEAD(&resource_list);
> @@ -85,7 +90,24 @@ struct amba_device *acpi_create_amba_device(struct acpi_device *adev,
>  			memcpy(resource, rentry->res, sizeof(struct resource));
>  	}
>  
> -	amba_dev = amba_device_alloc(dev_name(&adev->dev),
> +	/*
> +	 * The memory address of AMD pl330 has an offset of ACPI
> +	 * mem resource.
> +	 */
> +	if (quirk->quirk & BASE_OFFSET_QUIRK)
> +		resource->start += quirk->base_offset;
> +
> +	/*
> +	 * If the ACPI device already has a node attached. It must be
> +	 * renamed.
> +	 */
> +	if (quirk->quirk & MULTI_ATTACHED_QUIRK)
> +		sprintf(amba_devname, "%s%s", dev_name(&adev->dev), "DMA");
> +	else
> +		memcpy(amba_devname, dev_name(&adev->dev),
> +		       strlen(dev_name(&adev->dev)));
> +
> +	amba_dev = amba_device_alloc(amba_devname,
>  				     resource->start,
>  				     resource_size(resource));
>  

Isn't this basially an MFD in a rather odd fashion?

I would have though having a device which just splits the resources then
creates 2 children would be a whole lot simpler?

Graeme


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

* RE: [PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description
  2015-12-04 12:21       ` Borislav Petkov
@ 2015-12-04 13:19         ` Wan, Vincent
  -1 siblings, 0 replies; 52+ messages in thread
From: Wan, Vincent @ 2015-12-04 13:19 UTC (permalink / raw)
  To: Borislav Petkov, Wang, Annie
  Cc: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Huang, Ray, Xue, Ken, Li, Tony

> > +	ivrs_acpihid	[HW,X86_64]
> > +			Provide an override to the ACPI-HID:UID<->DEVICE-ID
> > +			mapping provided in the IVRS ACPI table. For
> > +			example, to map UART-HID:UID AMD0020:0 to
> > +			PCI device 00:14.5 write the parameter as:
> > +				ivrs_acpihid[00:14.5]=AMD0020:0
> 
> What is that parameter needed for? Can't you deduce the mapping from the
> hardware?

It is very like ivrs_ioapic/ ivrs_hpet, which can override the dedicated BDF id mapped to HID:UID that was reported from BIOS's IVHD entry.
If BIOS did not report a right BDF, we can resort to this parameter to correct it.

> 
> --
> Regards/Gruss,
>     Boris.
> 
> ECO tip #101: Trim your mails when you reply.

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

* RE: [PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description
@ 2015-12-04 13:19         ` Wan, Vincent
  0 siblings, 0 replies; 52+ messages in thread
From: Wan, Vincent @ 2015-12-04 13:19 UTC (permalink / raw)
  To: Borislav Petkov, Wang, Annie
  Cc: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Huang, Ray, Xue, Ken, Li, Tony

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 850 bytes --]

> > +	ivrs_acpihid	[HW,X86_64]
> > +			Provide an override to the ACPI-HID:UID<->DEVICE-ID
> > +			mapping provided in the IVRS ACPI table. For
> > +			example, to map UART-HID:UID AMD0020:0 to
> > +			PCI device 00:14.5 write the parameter as:
> > +				ivrs_acpihid[00:14.5]=AMD0020:0
> 
> What is that parameter needed for? Can't you deduce the mapping from the
> hardware?

It is very like ivrs_ioapic/ ivrs_hpet, which can override the dedicated BDF id mapped to HID:UID that was reported from BIOS's IVHD entry.
If BIOS did not report a right BDF, we can resort to this parameter to correct it.

> 
> --
> Regards/Gruss,
>     Boris.
> 
> ECO tip #101: Trim your mails when you reply.
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* Re: [PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description
  2015-12-04 13:19         ` Wan, Vincent
  (?)
@ 2015-12-04 14:38         ` Borislav Petkov
  -1 siblings, 0 replies; 52+ messages in thread
From: Borislav Petkov @ 2015-12-04 14:38 UTC (permalink / raw)
  To: Wan, Vincent
  Cc: Wang, Annie, Vinod Koul, Mika Westerberg, Joerg Roedel,
	Greg Kroah-Hartman, Rafael J. Wysocki, linux-acpi, linux-kernel,
	linux-serial, dmaengine, iommu, Huang, Ray, Xue, Ken, Li, Tony

On Fri, Dec 04, 2015 at 01:19:35PM +0000, Wan, Vincent wrote:
> > > +	ivrs_acpihid	[HW,X86_64]
> > > +			Provide an override to the ACPI-HID:UID<->DEVICE-ID
> > > +			mapping provided in the IVRS ACPI table. For
> > > +			example, to map UART-HID:UID AMD0020:0 to
> > > +			PCI device 00:14.5 write the parameter as:
> > > +				ivrs_acpihid[00:14.5]=AMD0020:0
> > 
> > What is that parameter needed for? Can't you deduce the mapping from the
> > hardware?
> 
> It is very like ivrs_ioapic/ ivrs_hpet, which can override the dedicated BDF id mapped to HID:UID that was reported from BIOS's IVHD entry.
> If BIOS did not report a right BDF, we can resort to this parameter to correct it.

Please add a verbose, human-readable explanation to the text so that
people know what it is for. The text above is hard to parse even for
insiders.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

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

* Re: [PATCH 6/9] dmaengine:pl330: set segment_boundary_mask = 0cffffffff
  2015-12-04  3:24   ` Wang Hongcheng
  (?)
@ 2015-12-04 14:59   ` Robin Murphy
  -1 siblings, 0 replies; 52+ messages in thread
From: Robin Murphy @ 2015-12-04 14:59 UTC (permalink / raw)
  To: Wang Hongcheng, Vinod Koul, Mika Westerberg, Joerg Roedel,
	Greg Kroah-Hartman, Rafael J. Wysocki
  Cc: Tony Li, Wan Zongshun, linux-kernel, linux-acpi, iommu,
	Huang Rui, Borislav Petkov, linux-serial, dmaengine, Ken Xue

On 04/12/15 03:24, Wang Hongcheng wrote:
> Because amd iommu and software iommu need this mask.For example,
> if we use software iommu without this mask, we will
> get 'Out of SW-IOMMU space' error, when calling swiotlb_map_page
> function.

The commit title doesn't match the code, but either way this patch 
should now be unnecessary: 002edb6f6f2a ("dma-mapping: tidy up dma_parms 
default handling") resolves the problem at its source, and is already in 
4.4-rc1.

(Incidentally, it was specifically the same PL330/SWIOTLB combination 
that led to that patch in the first place)

Robin.

> Signed-off-by: Wan Zongshun <Vincent.Wan@amd.com>
> Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
> ---
>   drivers/dma/pl330.c | 4 ++++
>   1 file changed, 4 insertions(+)
>
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 9d7af0d..fb46fdf 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -2966,6 +2966,10 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>   	if (ret)
>   		dev_err(&adev->dev, "unable to set the seg size\n");
>
> +	dev_info(&adev->dev, "set the seg boundary\n");
> +	ret = dma_set_seg_boundary(&adev->dev, 0xffffffff);
> +	if (ret)
> +		dev_err(&adev->dev, "unable to set the seg boundary\n");
>
>   	dev_info(&adev->dev,
>   		 "Loaded driver for PL330 DMAC-%x\n", adev->periphid);
>


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

* Re: [PATCH 4/9] dmaengine: pl330: add new items for pl330 private data
  2015-12-04  3:24   ` Wang Hongcheng
  (?)
@ 2015-12-10  4:09   ` Vinod Koul
  2015-12-10  6:38     ` Wang, Annie
  -1 siblings, 1 reply; 52+ messages in thread
From: Vinod Koul @ 2015-12-10  4:09 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Huang Rui, Wan Zongshun,
	Ken Xue, Tony Li

On Fri, Dec 04, 2015 at 11:24:21AM +0800, Wang Hongcheng wrote:
> has_no_cap_mask means this device has no preset cap mask.
> mcbuf_sz means bytes to allocate for MC buffer.

MC ?

> flags is for irq sharing, default is non-shared, in AMD
> Carrizo, pl330 shares IRQ with its corresponding UART device.
> 
> Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
> ---
>  drivers/acpi/acpi_apd.c    | 13 ++++++++++++-
>  drivers/dma/pl330.c        | 19 +++++++++++++------
>  include/linux/amba/pl330.h |  3 +++
>  3 files changed, 28 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
> index eb3316a..7a582f5 100644
> --- a/drivers/acpi/acpi_apd.c
> +++ b/drivers/acpi/acpi_apd.c
> @@ -21,6 +21,7 @@
>  #include <linux/amba/bus.h>
>  #include <linux/kernel.h>
>  #include <linux/sizes.h>
> +#include <linux/amba/pl330.h>
>  #include <linux/interrupt.h>
>  
>  #include "internal.h"
> @@ -35,6 +36,16 @@ struct apd_private_data;
>  #define ACPI_APD_SYSFS	BIT(0)
>  #define ACPI_APD_PM	BIT(1)
>  
> +static u8 peri_id[2] = { 0, 1 };
> +
> +static struct dma_pl330_platdata amd_pl330 = {
> +	.nr_valid_peri = 2,
> +	.peri_id = peri_id,
> +	.has_no_cap_mask = true,
> +	.mcbuf_sz = 0,
> +	.flags = IRQF_SHARED,
> +};

Why not DT or ACPI for this?

-- 
~Vinod

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

* RE: [PATCH 4/9] dmaengine: pl330: add new items for pl330 private data
  2015-12-10  4:09   ` Vinod Koul
@ 2015-12-10  6:38     ` Wang, Annie
       [not found]       ` <BLUPR12MB0433B81BB0AEB2D84505B55881E90-7LeqcoF/hwrdEWIfrEWxYwdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  0 siblings, 1 reply; 52+ messages in thread
From: Wang, Annie @ 2015-12-10  6:38 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Huang, Ray, Wan, Vincent, Xue,
	Ken, Li, Tony

>-----Original Message-----
>From: Vinod Koul [mailto:vinod.koul@intel.com]
>Sent: Thursday, December 10, 2015 12:09 PM
>To: Wang, Annie
>Cc: Mika Westerberg; Joerg Roedel; Greg Kroah-Hartman; Rafael J. Wysocki;
>linux-acpi@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
>serial@vger.kernel.org; dmaengine@vger.kernel.org; iommu@lists.linux-
>foundation.org; Borislav Petkov; Huang, Ray; Wan, Vincent; Xue, Ken; Li, Tony
>Subject: Re: [PATCH 4/9] dmaengine: pl330: add new items for pl330 private data
>
>On Fri, Dec 04, 2015 at 11:24:21AM +0800, Wang Hongcheng wrote:
>> has_no_cap_mask means this device has no preset cap mask.
>> mcbuf_sz means bytes to allocate for MC buffer.
>
>MC ?
Size of MicroCode buffers for each channel. I will update the comment.

>> flags is for irq sharing, default is non-shared, in AMD Carrizo, pl330
>> shares IRQ with its corresponding UART device.
>>
>> Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
>> ---
>>  drivers/acpi/acpi_apd.c    | 13 ++++++++++++-
>>  drivers/dma/pl330.c        | 19 +++++++++++++------
>>  include/linux/amba/pl330.h |  3 +++
>>  3 files changed, 28 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index
>> eb3316a..7a582f5 100644
>> --- a/drivers/acpi/acpi_apd.c
>> +++ b/drivers/acpi/acpi_apd.c
>> @@ -21,6 +21,7 @@
>>  #include <linux/amba/bus.h>
>>  #include <linux/kernel.h>
>>  #include <linux/sizes.h>
>> +#include <linux/amba/pl330.h>
>>  #include <linux/interrupt.h>
>>
>>  #include "internal.h"
>> @@ -35,6 +36,16 @@ struct apd_private_data;
>>  #define ACPI_APD_SYSFS	BIT(0)
>>  #define ACPI_APD_PM	BIT(1)
>>
>> +static u8 peri_id[2] = { 0, 1 };
>> +
>> +static struct dma_pl330_platdata amd_pl330 = {
>> +	.nr_valid_peri = 2,
>> +	.peri_id = peri_id,
>> +	.has_no_cap_mask = true,
>> +	.mcbuf_sz = 0,
>> +	.flags = IRQF_SHARED,
>> +};
>
>Why not DT or ACPI for this?
>
>--
>~Vinod

We choose to use private data, as pl330 already has  struct dma_pl330_platdata. 
Physically DMA share ACPI device with UART, however, BIOS believes DMA and UART is one device.
We can't  get irq share info from ACPI. And we don't use DT. 

Regards,
Annie





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

* RE: [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config
  2015-12-04 13:16   ` Graeme Gregory
@ 2015-12-11  6:57     ` Wang, Annie
       [not found]       ` <BLUPR12MB04339648B98F07977B6FA61F81EA0-7LeqcoF/hwrdEWIfrEWxYwdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  0 siblings, 1 reply; 52+ messages in thread
From: Wang, Annie @ 2015-12-11  6:57 UTC (permalink / raw)
  To: Graeme Gregory
  Cc: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Huang, Ray, Wan, Vincent, Xue,
	Ken, Li, Tony

>-----Original Message-----
>From: Graeme Gregory [mailto:gg@slimlogic.co.uk]
>Sent: Friday, December 04, 2015 9:16 PM
>To: Wang, Annie
>Cc: Vinod Koul; Mika Westerberg; Joerg Roedel; Greg Kroah-Hartman; Rafael J.
>Wysocki; linux-acpi@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
>serial@vger.kernel.org; dmaengine@vger.kernel.org; iommu@lists.linux-
>foundation.org; Borislav Petkov; Huang, Ray; Wan, Vincent; Xue, Ken; Li, Tony
>Subject: Re: [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330
>specific device config
>
>On Fri, Dec 04, 2015 at 11:24:20AM +0800, Wang Hongcheng wrote:
>> AMD pl330 is a UART DMA device, it shares one ACPI item with UART. So
>> a platform device and an acpi device will be created according to
>> AMD0020 ACPI dev. And its mem base address must have an offset. As a
>> result, MULTI_ATTACHED_QUIRK and MULTI_ATTACHED_QUIRK are used.
>>
>> Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
>> ---
>>  drivers/acpi/acpi_amba.c | 31 +++++++++++++++++++++++----
>> drivers/acpi/acpi_apd.c  | 56 +++++++++++++++++++++++++++++++++++++------
>-----
>>  include/linux/acpi.h     | 13 +++++++++--
>>  3 files changed, 81 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c index
>> 4f0366a..8a5269c 100644
>> --- a/drivers/acpi/acpi_amba.c
>> +++ b/drivers/acpi/acpi_amba.c
>> @@ -31,6 +31,8 @@ ACPI_MODULE_NAME("amba");
>>   * @periphid: AMBA device periphid.
>>   * @fixed_rate: Clock frequency.
>>   * @pdata: Platform data specific to the device.
>> + * @quirk: Specific device config, including device multiattach.
>> + * and mem base offset.
>>   *
>>   * Check if the given @adev can be represented as an AMBA device and, if
>>   * that's the case, create and register an AMBA device, populate its
>> @@ -42,7 +44,8 @@ ACPI_MODULE_NAME("amba");  struct amba_device
>> *acpi_create_amba_device(struct acpi_device *adev,
>>  					    unsigned int periphid,
>>  					    unsigned long fixed_rate,
>> -					    void *pdata)
>> +					    void *pdata,
>> +					    struct acpi_amba_quirk *quirk)
>>  {
>>  	struct amba_device *amba_dev = NULL;
>>  	struct device *parent;
>> @@ -54,12 +57,14 @@ struct amba_device *acpi_create_amba_device(struct
>acpi_device *adev,
>>  	unsigned int i;
>>  	unsigned int irq[AMBA_NR_IRQS];
>>  	struct clk *clk = ERR_PTR(-ENODEV);
>> +	char amba_devname[100];
>>
>>  	/*
>>  	 * If the ACPI node already has a physical device attached,
>> -	 * skip it.
>> +	 * skip it. Except some special devices such as AMD0020 which
>> +	 * needs attach physical devices two times.
>>  	 */
>> -	if (adev->physical_node_count)
>> +	if (adev->physical_node_count && !(quirk->quirk &
>> +MULTI_ATTACHED_QUIRK))
>>  		return NULL;
>>
>>  	INIT_LIST_HEAD(&resource_list);
>> @@ -85,7 +90,24 @@ struct amba_device *acpi_create_amba_device(struct
>acpi_device *adev,
>>  			memcpy(resource, rentry->res, sizeof(struct resource));
>>  	}
>>
>> -	amba_dev = amba_device_alloc(dev_name(&adev->dev),
>> +	/*
>> +	 * The memory address of AMD pl330 has an offset of ACPI
>> +	 * mem resource.
>> +	 */
>> +	if (quirk->quirk & BASE_OFFSET_QUIRK)
>> +		resource->start += quirk->base_offset;
>> +
>> +	/*
>> +	 * If the ACPI device already has a node attached. It must be
>> +	 * renamed.
>> +	 */
>> +	if (quirk->quirk & MULTI_ATTACHED_QUIRK)
>> +		sprintf(amba_devname, "%s%s", dev_name(&adev->dev),
>"DMA");
>> +	else
>> +		memcpy(amba_devname, dev_name(&adev->dev),
>> +		       strlen(dev_name(&adev->dev)));
>> +
>> +	amba_dev = amba_device_alloc(amba_devname,
>>  				     resource->start,
>>  				     resource_size(resource));
>>
>
>Isn't this basially an MFD in a rather odd fashion?
>
>I would have though having a device which just splits the resources then creates 2
>children would be a whole lot simpler?
>
>Graeme

It seems more complex, if I  trans an ACPI device to pdev, then attach 2 platform child nodes,
and create an amba device refer to one of the childs. Too many trans. 

Thanks,
Hongcheng(Annie)

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

* Re: [PATCH 4/9] dmaengine: pl330: add new items for pl330 private data
  2015-12-10  6:38     ` Wang, Annie
@ 2015-12-11  9:29           ` Vinod Koul
  0 siblings, 0 replies; 52+ messages in thread
From: Vinod Koul @ 2015-12-11  9:29 UTC (permalink / raw)
  To: Wang, Annie
  Cc: Li, Tony, Wan, Vincent, Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Huang, Ray,
	Borislav Petkov, linux-serial-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, Mika Westerberg, Xue, Ken

On Thu, Dec 10, 2015 at 06:38:09AM +0000, Wang, Annie wrote:
> >
> >Why not DT or ACPI for this?
> >
> We choose to use private data, as pl330 already has  struct dma_pl330_platdata. 
> Physically DMA share ACPI device with UART, however, BIOS believes DMA and UART is one device.
> We can't  get irq share info from ACPI. And we don't use DT. 
> 
That should be then a MFD device

-- 
~Vinod

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

* Re: [PATCH 4/9] dmaengine: pl330: add new items for pl330 private data
@ 2015-12-11  9:29           ` Vinod Koul
  0 siblings, 0 replies; 52+ messages in thread
From: Vinod Koul @ 2015-12-11  9:29 UTC (permalink / raw)
  To: Wang, Annie
  Cc: Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Huang, Ray, Wan, Vincent, Xue,
	Ken, Li, Tony

On Thu, Dec 10, 2015 at 06:38:09AM +0000, Wang, Annie wrote:
> >
> >Why not DT or ACPI for this?
> >
> We choose to use private data, as pl330 already has  struct dma_pl330_platdata. 
> Physically DMA share ACPI device with UART, however, BIOS believes DMA and UART is one device.
> We can't  get irq share info from ACPI. And we don't use DT. 
> 
That should be then a MFD device

-- 
~Vinod

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

* Re: [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config
  2015-12-11  6:57     ` Wang, Annie
@ 2015-12-11  9:31           ` Vinod Koul
  0 siblings, 0 replies; 52+ messages in thread
From: Vinod Koul @ 2015-12-11  9:31 UTC (permalink / raw)
  To: Wang, Annie
  Cc: Li, Tony, Wan, Vincent, Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Huang, Ray,
	Borislav Petkov, Graeme Gregory,
	linux-serial-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, Mika Westerberg, Xue, Ken

On Fri, Dec 11, 2015 at 06:57:51AM +0000, Wang, Annie wrote:
> >> +	/*
> >> +	 * If the ACPI device already has a node attached. It must be
> >> +	 * renamed.
> >> +	 */
> >> +	if (quirk->quirk & MULTI_ATTACHED_QUIRK)
> >> +		sprintf(amba_devname, "%s%s", dev_name(&adev->dev),
> >"DMA");
> >> +	else
> >> +		memcpy(amba_devname, dev_name(&adev->dev),
> >> +		       strlen(dev_name(&adev->dev)));
> >> +
> >> +	amba_dev = amba_device_alloc(amba_devname,
> >>  				     resource->start,
> >>  				     resource_size(resource));
> >>
> >
> >Isn't this basially an MFD in a rather odd fashion?

MFD yes, odd perhaps made out here!
> >
> >I would have though having a device which just splits the resources then creates 2
> >children would be a whole lot simpler?
> >
Yup!

> 
> It seems more complex, if I  trans an ACPI device to pdev, then attach 2 platform child nodes,
> and create an amba device refer to one of the childs. Too many trans. 

Sorry but I dont think that is right assumption, it will simper and PM would
become easy

-- 
~Vinod

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

* Re: [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config
@ 2015-12-11  9:31           ` Vinod Koul
  0 siblings, 0 replies; 52+ messages in thread
From: Vinod Koul @ 2015-12-11  9:31 UTC (permalink / raw)
  To: Wang, Annie
  Cc: Graeme Gregory, Mika Westerberg, Joerg Roedel,
	Greg Kroah-Hartman, Rafael J. Wysocki, linux-acpi, linux-kernel,
	linux-serial, dmaengine, iommu, Borislav Petkov, Huang, Ray, Wan,
	Vincent, Xue, Ken, Li, Tony

On Fri, Dec 11, 2015 at 06:57:51AM +0000, Wang, Annie wrote:
> >> +	/*
> >> +	 * If the ACPI device already has a node attached. It must be
> >> +	 * renamed.
> >> +	 */
> >> +	if (quirk->quirk & MULTI_ATTACHED_QUIRK)
> >> +		sprintf(amba_devname, "%s%s", dev_name(&adev->dev),
> >"DMA");
> >> +	else
> >> +		memcpy(amba_devname, dev_name(&adev->dev),
> >> +		       strlen(dev_name(&adev->dev)));
> >> +
> >> +	amba_dev = amba_device_alloc(amba_devname,
> >>  				     resource->start,
> >>  				     resource_size(resource));
> >>
> >
> >Isn't this basially an MFD in a rather odd fashion?

MFD yes, odd perhaps made out here!
> >
> >I would have though having a device which just splits the resources then creates 2
> >children would be a whole lot simpler?
> >
Yup!

> 
> It seems more complex, if I  trans an ACPI device to pdev, then attach 2 platform child nodes,
> and create an amba device refer to one of the childs. Too many trans. 

Sorry but I dont think that is right assumption, it will simper and PM would
become easy

-- 
~Vinod

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

* Re: [PATCH 4/9] dmaengine: pl330: add new items for pl330 private data
  2015-12-11  9:29           ` Vinod Koul
  (?)
@ 2015-12-11 13:56           ` Andy Shevchenko
  -1 siblings, 0 replies; 52+ messages in thread
From: Andy Shevchenko @ 2015-12-11 13:56 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Wang, Annie, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Huang, Ray, Wan, Vincent, Xue,
	Ken, Li, Tony

On Fri, Dec 11, 2015 at 11:29 AM, Vinod Koul <vinod.koul@intel.com> wrote:
> On Thu, Dec 10, 2015 at 06:38:09AM +0000, Wang, Annie wrote:
>> >
>> >Why not DT or ACPI for this?
>> >
>> We choose to use private data, as pl330 already has  struct dma_pl330_platdata.
>> Physically DMA share ACPI device with UART, however, BIOS believes DMA and UART is one device.
>> We can't  get irq share info from ACPI. And we don't use DT.
>>
> That should be then a MFD device

And for me seems like acpi_amba and drivers shall utilize unified
device property API.

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 5/9] dmaengine: pl330: provide ACPI dmaengine interface
  2015-12-04  3:24   ` Wang Hongcheng
@ 2015-12-13  2:21       ` Andy Shevchenko
  -1 siblings, 0 replies; 52+ messages in thread
From: Andy Shevchenko @ 2015-12-13  2:21 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: Tony Li, Wan Zongshun, Vinod Koul, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Huang Rui,
	Borislav Petkov, linux-serial-u79uwXL29TY76Z2rM5mHXA, dmaengine,
	Mika Westerberg, Ken Xue

On Fri, Dec 4, 2015 at 5:24 AM, Wang Hongcheng <annie.wang-5C7GfCeVMHo@public.gmane.org> wrote:
> register acpi_dma controller, so ACPI devices can request pl330 DMA
> channel.
> A filter is added in private data for Carrizo specific hardware
> design
>
> Signed-off-by: Wang Hongcheng <annie.wang-5C7GfCeVMHo@public.gmane.org>
> ---
>  drivers/acpi/acpi_apd.c    | 12 ++++++++++++
>  drivers/dma/pl330.c        | 38 ++++++++++++++++++++++++++++++++++++++
>  include/linux/amba/pl330.h |  1 +
>  3 files changed, 51 insertions(+)
>
> diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
> index 7a582f5..906a20f 100644
> --- a/drivers/acpi/acpi_apd.c
> +++ b/drivers/acpi/acpi_apd.c
> @@ -38,12 +38,15 @@ struct apd_private_data;
>
>  static u8 peri_id[2] = { 0, 1 };
>
> +static int apd_acpi_xlate_filter(int slave_id, struct device *dev);
> +
>  static struct dma_pl330_platdata amd_pl330 = {
>         .nr_valid_peri = 2,
>         .peri_id = peri_id,
>         .has_no_cap_mask = true,
>         .mcbuf_sz = 0,
>         .flags = IRQF_SHARED,
> +       .acpi_xlate_filter = apd_acpi_xlate_filter,
>  };
>
>  /**
> @@ -68,6 +71,15 @@ struct apd_private_data {
>         const struct apd_device_desc *dev_desc;
>  };
>
> +int apd_acpi_xlate_filter(int slave_id, struct device *dev)
> +{
> +       if (((slave_id == 1) && (!strcmp(dev_name(dev), "AMD0020:00DMA")))
> +           || ((slave_id == 2) && (!strcmp(dev_name(dev), "AMD0020:01DMA"))))
> +               return 0;

First of all, too many parens. No need to have them here: (!strcmp()),
for example.

Second, looks like you actually compare slave_id with device _UID, am
I right? In that case maybe better to check device's _HID, _UID and
eventually slave_id.

> +
> +       return 1;
> +}
> +
>  #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
>  #define APD_ADDR(desc) ((unsigned long)&desc)
>
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 8300969..9d7af0d 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -2079,6 +2079,35 @@ static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec,
>         return dma_get_slave_channel(&pl330->peripherals[chan_id].chan);
>  }
>
> +static struct dma_chan *acpi_dma_pl330_xlate(struct acpi_dma_spec *dma_spec,
> +                                            struct acpi_dma *adma)
> +{
> +       struct pl330_dmac *pl330 = adma->data;
> +       struct dma_pl330_platdata *pdat;
> +       unsigned int chan_id;
> +       int ret;
> +
> +       if (!dma_spec)
> +               return NULL;

AFAIR dma_spec is guaranteed not to be NULL.

> +
> +       if (!adma)
> +               return NULL;

Ditto.

> +
> +       pdat = dev_get_platdata(adma->dev);
> +
> +       chan_id = dma_spec->chan_id;
> +       if (chan_id >= pl330->num_peripherals)
> +               return NULL;
> +
> +       if (pdat->acpi_xlate_filter) {
> +               ret = pdat->acpi_xlate_filter(dma_spec->slave_id, adma->dev);
> +               if (ret)
> +                       return NULL;
> +       }
> +
> +       return dma_get_slave_channel(&pl330->peripherals[chan_id].chan);
> +}
> +
>  static int pl330_alloc_chan_resources(struct dma_chan *chan)
>  {
>         struct dma_pl330_chan *pch = to_pchan(chan);
> @@ -2918,6 +2947,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>                 }
>         }
>
> +       if (ACPI_HANDLE(&adev->dev)) {

I suspect where did you get this, but it's already updated. You better use
has_acpi_companion() instead.

> +               ret = acpi_dma_controller_register(&adev->dev,
> +                                                  acpi_dma_pl330_xlate, pl330);

So, someone has either to provide CSRT (which is mostly foreign to
ACPI tables), or to provide those resources somehow else (request line
base and number). In the latter case you would need to add the hook
into acpi_dma_controller_register().

> +               if (ret) {
> +                       dev_err(&adev->dev,
> +                               "unable to register DMA to the generic ACPI DMA helpers\n");
> +               }
> +       }
> +
>         adev->dev.dma_parms = &pl330->dma_parms;
>
>         /*

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 5/9] dmaengine: pl330: provide ACPI dmaengine interface
@ 2015-12-13  2:21       ` Andy Shevchenko
  0 siblings, 0 replies; 52+ messages in thread
From: Andy Shevchenko @ 2015-12-13  2:21 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Huang Rui, Wan Zongshun,
	Ken Xue, Tony Li

On Fri, Dec 4, 2015 at 5:24 AM, Wang Hongcheng <annie.wang@amd.com> wrote:
> register acpi_dma controller, so ACPI devices can request pl330 DMA
> channel.
> A filter is added in private data for Carrizo specific hardware
> design
>
> Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
> ---
>  drivers/acpi/acpi_apd.c    | 12 ++++++++++++
>  drivers/dma/pl330.c        | 38 ++++++++++++++++++++++++++++++++++++++
>  include/linux/amba/pl330.h |  1 +
>  3 files changed, 51 insertions(+)
>
> diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
> index 7a582f5..906a20f 100644
> --- a/drivers/acpi/acpi_apd.c
> +++ b/drivers/acpi/acpi_apd.c
> @@ -38,12 +38,15 @@ struct apd_private_data;
>
>  static u8 peri_id[2] = { 0, 1 };
>
> +static int apd_acpi_xlate_filter(int slave_id, struct device *dev);
> +
>  static struct dma_pl330_platdata amd_pl330 = {
>         .nr_valid_peri = 2,
>         .peri_id = peri_id,
>         .has_no_cap_mask = true,
>         .mcbuf_sz = 0,
>         .flags = IRQF_SHARED,
> +       .acpi_xlate_filter = apd_acpi_xlate_filter,
>  };
>
>  /**
> @@ -68,6 +71,15 @@ struct apd_private_data {
>         const struct apd_device_desc *dev_desc;
>  };
>
> +int apd_acpi_xlate_filter(int slave_id, struct device *dev)
> +{
> +       if (((slave_id == 1) && (!strcmp(dev_name(dev), "AMD0020:00DMA")))
> +           || ((slave_id == 2) && (!strcmp(dev_name(dev), "AMD0020:01DMA"))))
> +               return 0;

First of all, too many parens. No need to have them here: (!strcmp()),
for example.

Second, looks like you actually compare slave_id with device _UID, am
I right? In that case maybe better to check device's _HID, _UID and
eventually slave_id.

> +
> +       return 1;
> +}
> +
>  #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
>  #define APD_ADDR(desc) ((unsigned long)&desc)
>
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 8300969..9d7af0d 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -2079,6 +2079,35 @@ static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec,
>         return dma_get_slave_channel(&pl330->peripherals[chan_id].chan);
>  }
>
> +static struct dma_chan *acpi_dma_pl330_xlate(struct acpi_dma_spec *dma_spec,
> +                                            struct acpi_dma *adma)
> +{
> +       struct pl330_dmac *pl330 = adma->data;
> +       struct dma_pl330_platdata *pdat;
> +       unsigned int chan_id;
> +       int ret;
> +
> +       if (!dma_spec)
> +               return NULL;

AFAIR dma_spec is guaranteed not to be NULL.

> +
> +       if (!adma)
> +               return NULL;

Ditto.

> +
> +       pdat = dev_get_platdata(adma->dev);
> +
> +       chan_id = dma_spec->chan_id;
> +       if (chan_id >= pl330->num_peripherals)
> +               return NULL;
> +
> +       if (pdat->acpi_xlate_filter) {
> +               ret = pdat->acpi_xlate_filter(dma_spec->slave_id, adma->dev);
> +               if (ret)
> +                       return NULL;
> +       }
> +
> +       return dma_get_slave_channel(&pl330->peripherals[chan_id].chan);
> +}
> +
>  static int pl330_alloc_chan_resources(struct dma_chan *chan)
>  {
>         struct dma_pl330_chan *pch = to_pchan(chan);
> @@ -2918,6 +2947,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>                 }
>         }
>
> +       if (ACPI_HANDLE(&adev->dev)) {

I suspect where did you get this, but it's already updated. You better use
has_acpi_companion() instead.

> +               ret = acpi_dma_controller_register(&adev->dev,
> +                                                  acpi_dma_pl330_xlate, pl330);

So, someone has either to provide CSRT (which is mostly foreign to
ACPI tables), or to provide those resources somehow else (request line
base and number). In the latter case you would need to add the hook
into acpi_dma_controller_register().

> +               if (ret) {
> +                       dev_err(&adev->dev,
> +                               "unable to register DMA to the generic ACPI DMA helpers\n");
> +               }
> +       }
> +
>         adev->dev.dma_parms = &pl330->dma_parms;
>
>         /*

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 7/9] Serial:8250: New Port Type PORT_AMD_8250
  2015-12-04  3:24   ` Wang Hongcheng
@ 2015-12-13  2:30       ` Andy Shevchenko
  -1 siblings, 0 replies; 52+ messages in thread
From: Andy Shevchenko @ 2015-12-13  2:30 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: Tony Li, Wan Zongshun, Vinod Koul, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Huang Rui,
	Borislav Petkov, linux-serial-u79uwXL29TY76Z2rM5mHXA, dmaengine,
	Mika Westerberg, Ken Xue

On Fri, Dec 4, 2015 at 5:24 AM, Wang Hongcheng <annie.wang-5C7GfCeVMHo@public.gmane.org> wrote:
> Set a new port type for AMD Carrizo.  Add has_pl330_dma to 8250_dw's
> private data and init fcr,ier as well as dma rx size.
>
> Signed-off-by: Wang Hongcheng <annie.wang-5C7GfCeVMHo@public.gmane.org>
> ---
>  drivers/acpi/acpi_apd.c             | 10 ++++++++++
>  drivers/tty/serial/8250/8250_dw.c   | 16 ++++++++++++++++
>  drivers/tty/serial/8250/8250_port.c |  9 +++++++++
>  include/linux/serial_8250.h         |  4 ++++
>  include/uapi/linux/serial_core.h    |  3 ++-
>  include/uapi/linux/serial_reg.h     |  2 ++
>  6 files changed, 43 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
> index 906a20f..787f477 100644
> --- a/drivers/acpi/acpi_apd.c
> +++ b/drivers/acpi/acpi_apd.c
> @@ -23,6 +23,7 @@
>  #include <linux/sizes.h>
>  #include <linux/amba/pl330.h>
>  #include <linux/interrupt.h>
> +#include <linux/serial_8250.h>
>
>  #include "internal.h"
>
> @@ -49,6 +50,10 @@ static struct dma_pl330_platdata amd_pl330 = {
>         .acpi_xlate_filter = apd_acpi_xlate_filter,
>  };
>
> +static struct plat_dw8250_data amd_dw8250 = {
> +       .has_pl330_dma = 1,
> +};
> +
>  /**
>   * struct apd_device_desc - a descriptor for apd device.
>   * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM;
> @@ -164,6 +169,11 @@ static int acpi_apd_create_device(struct acpi_device *adev,
>                 goto err_out;
>
>         if (!strncmp(pdev->name, "AMD0020", 7)) {
> +               ret = platform_device_add_data(pdev, &amd_dw8250,
> +                                              sizeof(amd_dw8250));
> +               if (ret)
> +                       goto err_out;
> +
>                 memset(&amba_quirks, 0, sizeof(amba_quirks));
>                 setup_quirks(pdev, &amba_quirks);
>
> diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
> index a5d319e..a5ae9b6 100644
> --- a/drivers/tty/serial/8250/8250_dw.c
> +++ b/drivers/tty/serial/8250/8250_dw.c
> @@ -66,6 +66,8 @@ struct dw8250_data {
>
>         unsigned int            skip_autocfg:1;
>         unsigned int            uart_16550_compatible:1;

> +

Remove this

> +       unsigned                has_pl330_dma:1;

Use unsigned int.

>  };
>
>  #define BYT_PRV_CLK                    0x800
> @@ -304,6 +306,7 @@ static void dw8250_setup_port(struct uart_port *p)
>  {
>         struct uart_8250_port *up = up_to_u8250p(p);
>         u32 reg;
> +       struct dw8250_data *d = p->private_data;

Rename d -> data and move the line to be second in the definition list.

>
>         /*
>          * If the Component Version Register returns zero, we know that
> @@ -326,6 +329,16 @@ static void dw8250_setup_port(struct uart_port *p)
>                 p->flags |= UPF_FIXED_TYPE;
>                 p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
>                 up->capabilities = UART_CAP_FIFO;
> +               if (d->has_pl330_dma) {
> +                       p->type = PORT_AMD_8250;

> +                       p->flags |= UPF_SHARE_IRQ;

Isn't it a default?

> +
> +                       up->ier |= UART_IER_PTIME | UART_IER_THRI |
> +                               UART_IER_RLSI | UART_IER_RDI;
> +                       up->fcr |= UART_FCR_R_TRIG_10 | UART_FCR_T_TRIG_11 |
> +                               UART_FCR_DMA_SELECT;
> +                       up->tx_loadsz = p->fifosize / 2;
> +               }
>         }
>
>         if (reg & DW_UART_CPR_AFCE_MODE)
> @@ -339,6 +352,7 @@ static int dw8250_probe(struct platform_device *pdev)
>         int irq = platform_get_irq(pdev, 0);
>         struct uart_port *p = &uart.port;
>         struct dw8250_data *data;
> +       struct plat_dw8250_data *pdata = dev_get_platdata(&pdev->dev);
>         int err;
>         u32 val;
>
> @@ -468,6 +482,7 @@ static int dw8250_probe(struct platform_device *pdev)
>                 p->handle_irq = NULL;
>         }
>
> +       data->has_pl330_dma = pdata ? pdata->has_pl330_dma : 0;
>         if (!data->skip_autocfg)
>                 dw8250_setup_port(p);
>
> @@ -475,6 +490,7 @@ static int dw8250_probe(struct platform_device *pdev)
>         if (p->fifosize) {
>                 data->dma.rxconf.src_maxburst = p->fifosize / 4;
>                 data->dma.txconf.dst_maxburst = p->fifosize / 4;
> +               data->dma.rx_size = data->has_pl330_dma ? (p->fifosize / 2 + 2) : 0;
>                 uart.dma = &data->dma;
>         }
>
> diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
> index 52d82d2..b258edc 100644
> --- a/drivers/tty/serial/8250/8250_port.c
> +++ b/drivers/tty/serial/8250/8250_port.c
> @@ -269,6 +269,15 @@ configured less than Maximum supported fifo bytes */
>                 .rxtrig_bytes   = {1, 4, 8, 14},
>                 .flags          = UART_CAP_FIFO,
>         },
> +       [PORT_AMD_8250] = {
> +               .name           = "AMD_8250",
> +               .fifo_size      = 256,
> +               .tx_loadsz      = 128,
> +               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
> +                               UART_FCR_T_TRIG_11 | UART_FCR_DMA_SELECT,

So, do  your HW has no additional wires to DMA engine? This bit
usually is ignored if DMA has more signal lines connected to UART IP.
Please, check this.

> +               .rxtrig_bytes   = {1, 4, 8},
> +               .flags          = UART_CAP_FIFO,
> +       },
>  };
>
>  /* Uart divisor latch read */
> diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
> index faa0e03..4652783 100644
> --- a/include/linux/serial_8250.h
> +++ b/include/linux/serial_8250.h
> @@ -42,6 +42,10 @@ struct plat_serial8250_port {
>         void            (*handle_break)(struct uart_port *);
>  };
>
> +struct plat_dw8250_data {
> +       unsigned has_pl330_dma:1;
> +};

It should be a part of include/linux/platform_data

> +
>  /*
>   * Allocate 8250 platform device IDs.  Nothing is implied by
>   * the numbering here, except for the legacy entry being -1.
> diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
> index 93ba148..6a06651 100644
> --- a/include/uapi/linux/serial_core.h
> +++ b/include/uapi/linux/serial_core.h
> @@ -56,7 +56,8 @@
>  #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */
>  #define PORT_RT2880    29      /* Ralink RT2880 internal UART */
>  #define PORT_16550A_FSL64 30   /* Freescale 16550 UART with 64 FIFOs */
> -#define PORT_MAX_8250  30      /* max port ID */
> +#define PORT_AMD_8250  31
> +#define PORT_MAX_8250  32      /* max port ID */
>
>  /*
>   * ARM specific type numbers.  These are not currently guaranteed
> diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h
> index 1e5ac4e7..13e8294 100644
> --- a/include/uapi/linux/serial_reg.h
> +++ b/include/uapi/linux/serial_reg.h
> @@ -25,6 +25,8 @@
>  #define UART_IER_RLSI          0x04 /* Enable receiver line status interrupt */
>  #define UART_IER_THRI          0x02 /* Enable Transmitter holding register int. */
>  #define UART_IER_RDI           0x01 /* Enable receiver data interrupt */
> +/* Enable Programmable Transmitter holding register int. */
> +#define UART_IER_PTIME          0x80

Move this to be first in the list. Put comment at the end of the line

>  /*
>   * Sleep mode for ST16650 and TI16750.  For the ST16650, EFR[4]=1
>   */
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 7/9] Serial:8250: New Port Type PORT_AMD_8250
@ 2015-12-13  2:30       ` Andy Shevchenko
  0 siblings, 0 replies; 52+ messages in thread
From: Andy Shevchenko @ 2015-12-13  2:30 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Huang Rui, Wan Zongshun,
	Ken Xue, Tony Li

On Fri, Dec 4, 2015 at 5:24 AM, Wang Hongcheng <annie.wang@amd.com> wrote:
> Set a new port type for AMD Carrizo.  Add has_pl330_dma to 8250_dw's
> private data and init fcr,ier as well as dma rx size.
>
> Signed-off-by: Wang Hongcheng <annie.wang@amd.com>
> ---
>  drivers/acpi/acpi_apd.c             | 10 ++++++++++
>  drivers/tty/serial/8250/8250_dw.c   | 16 ++++++++++++++++
>  drivers/tty/serial/8250/8250_port.c |  9 +++++++++
>  include/linux/serial_8250.h         |  4 ++++
>  include/uapi/linux/serial_core.h    |  3 ++-
>  include/uapi/linux/serial_reg.h     |  2 ++
>  6 files changed, 43 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
> index 906a20f..787f477 100644
> --- a/drivers/acpi/acpi_apd.c
> +++ b/drivers/acpi/acpi_apd.c
> @@ -23,6 +23,7 @@
>  #include <linux/sizes.h>
>  #include <linux/amba/pl330.h>
>  #include <linux/interrupt.h>
> +#include <linux/serial_8250.h>
>
>  #include "internal.h"
>
> @@ -49,6 +50,10 @@ static struct dma_pl330_platdata amd_pl330 = {
>         .acpi_xlate_filter = apd_acpi_xlate_filter,
>  };
>
> +static struct plat_dw8250_data amd_dw8250 = {
> +       .has_pl330_dma = 1,
> +};
> +
>  /**
>   * struct apd_device_desc - a descriptor for apd device.
>   * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM;
> @@ -164,6 +169,11 @@ static int acpi_apd_create_device(struct acpi_device *adev,
>                 goto err_out;
>
>         if (!strncmp(pdev->name, "AMD0020", 7)) {
> +               ret = platform_device_add_data(pdev, &amd_dw8250,
> +                                              sizeof(amd_dw8250));
> +               if (ret)
> +                       goto err_out;
> +
>                 memset(&amba_quirks, 0, sizeof(amba_quirks));
>                 setup_quirks(pdev, &amba_quirks);
>
> diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
> index a5d319e..a5ae9b6 100644
> --- a/drivers/tty/serial/8250/8250_dw.c
> +++ b/drivers/tty/serial/8250/8250_dw.c
> @@ -66,6 +66,8 @@ struct dw8250_data {
>
>         unsigned int            skip_autocfg:1;
>         unsigned int            uart_16550_compatible:1;

> +

Remove this

> +       unsigned                has_pl330_dma:1;

Use unsigned int.

>  };
>
>  #define BYT_PRV_CLK                    0x800
> @@ -304,6 +306,7 @@ static void dw8250_setup_port(struct uart_port *p)
>  {
>         struct uart_8250_port *up = up_to_u8250p(p);
>         u32 reg;
> +       struct dw8250_data *d = p->private_data;

Rename d -> data and move the line to be second in the definition list.

>
>         /*
>          * If the Component Version Register returns zero, we know that
> @@ -326,6 +329,16 @@ static void dw8250_setup_port(struct uart_port *p)
>                 p->flags |= UPF_FIXED_TYPE;
>                 p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
>                 up->capabilities = UART_CAP_FIFO;
> +               if (d->has_pl330_dma) {
> +                       p->type = PORT_AMD_8250;

> +                       p->flags |= UPF_SHARE_IRQ;

Isn't it a default?

> +
> +                       up->ier |= UART_IER_PTIME | UART_IER_THRI |
> +                               UART_IER_RLSI | UART_IER_RDI;
> +                       up->fcr |= UART_FCR_R_TRIG_10 | UART_FCR_T_TRIG_11 |
> +                               UART_FCR_DMA_SELECT;
> +                       up->tx_loadsz = p->fifosize / 2;
> +               }
>         }
>
>         if (reg & DW_UART_CPR_AFCE_MODE)
> @@ -339,6 +352,7 @@ static int dw8250_probe(struct platform_device *pdev)
>         int irq = platform_get_irq(pdev, 0);
>         struct uart_port *p = &uart.port;
>         struct dw8250_data *data;
> +       struct plat_dw8250_data *pdata = dev_get_platdata(&pdev->dev);
>         int err;
>         u32 val;
>
> @@ -468,6 +482,7 @@ static int dw8250_probe(struct platform_device *pdev)
>                 p->handle_irq = NULL;
>         }
>
> +       data->has_pl330_dma = pdata ? pdata->has_pl330_dma : 0;
>         if (!data->skip_autocfg)
>                 dw8250_setup_port(p);
>
> @@ -475,6 +490,7 @@ static int dw8250_probe(struct platform_device *pdev)
>         if (p->fifosize) {
>                 data->dma.rxconf.src_maxburst = p->fifosize / 4;
>                 data->dma.txconf.dst_maxburst = p->fifosize / 4;
> +               data->dma.rx_size = data->has_pl330_dma ? (p->fifosize / 2 + 2) : 0;
>                 uart.dma = &data->dma;
>         }
>
> diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
> index 52d82d2..b258edc 100644
> --- a/drivers/tty/serial/8250/8250_port.c
> +++ b/drivers/tty/serial/8250/8250_port.c
> @@ -269,6 +269,15 @@ configured less than Maximum supported fifo bytes */
>                 .rxtrig_bytes   = {1, 4, 8, 14},
>                 .flags          = UART_CAP_FIFO,
>         },
> +       [PORT_AMD_8250] = {
> +               .name           = "AMD_8250",
> +               .fifo_size      = 256,
> +               .tx_loadsz      = 128,
> +               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
> +                               UART_FCR_T_TRIG_11 | UART_FCR_DMA_SELECT,

So, do  your HW has no additional wires to DMA engine? This bit
usually is ignored if DMA has more signal lines connected to UART IP.
Please, check this.

> +               .rxtrig_bytes   = {1, 4, 8},
> +               .flags          = UART_CAP_FIFO,
> +       },
>  };
>
>  /* Uart divisor latch read */
> diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
> index faa0e03..4652783 100644
> --- a/include/linux/serial_8250.h
> +++ b/include/linux/serial_8250.h
> @@ -42,6 +42,10 @@ struct plat_serial8250_port {
>         void            (*handle_break)(struct uart_port *);
>  };
>
> +struct plat_dw8250_data {
> +       unsigned has_pl330_dma:1;
> +};

It should be a part of include/linux/platform_data

> +
>  /*
>   * Allocate 8250 platform device IDs.  Nothing is implied by
>   * the numbering here, except for the legacy entry being -1.
> diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
> index 93ba148..6a06651 100644
> --- a/include/uapi/linux/serial_core.h
> +++ b/include/uapi/linux/serial_core.h
> @@ -56,7 +56,8 @@
>  #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */
>  #define PORT_RT2880    29      /* Ralink RT2880 internal UART */
>  #define PORT_16550A_FSL64 30   /* Freescale 16550 UART with 64 FIFOs */
> -#define PORT_MAX_8250  30      /* max port ID */
> +#define PORT_AMD_8250  31
> +#define PORT_MAX_8250  32      /* max port ID */
>
>  /*
>   * ARM specific type numbers.  These are not currently guaranteed
> diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h
> index 1e5ac4e7..13e8294 100644
> --- a/include/uapi/linux/serial_reg.h
> +++ b/include/uapi/linux/serial_reg.h
> @@ -25,6 +25,8 @@
>  #define UART_IER_RLSI          0x04 /* Enable receiver line status interrupt */
>  #define UART_IER_THRI          0x02 /* Enable Transmitter holding register int. */
>  #define UART_IER_RDI           0x01 /* Enable receiver data interrupt */
> +/* Enable Programmable Transmitter holding register int. */
> +#define UART_IER_PTIME          0x80

Move this to be first in the list. Put comment at the end of the line

>  /*
>   * Sleep mode for ST16650 and TI16750.  For the ST16650, EFR[4]=1
>   */
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 0/9] 8250: AMD Carrizo UART PL300 DMA enablement
  2015-12-04  3:24 ` Wang Hongcheng
                   ` (9 preceding siblings ...)
  (?)
@ 2015-12-13  2:32 ` Andy Shevchenko
  -1 siblings, 0 replies; 52+ messages in thread
From: Andy Shevchenko @ 2015-12-13  2:32 UTC (permalink / raw)
  To: Wang Hongcheng
  Cc: Vinod Koul, Mika Westerberg, Joerg Roedel, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-acpi, linux-kernel, linux-serial,
	dmaengine, iommu, Borislav Petkov, Huang Rui, Wan Zongshun,
	Ken Xue, Tony Li

On Fri, Dec 4, 2015 at 5:24 AM, Wang Hongcheng <annie.wang@amd.com> wrote:
> Hi all,
>
> As AMD carrizo UART device is compatible with 8250 and has pl330 DMA
> IP, our uart driver is serial:8250 and DMA engines are registered by
> driver/dma/pl330. The following patches are made, in order to enable
> DMA.
>
> Firstly, we add an universal ACPI amba glue layer to create an amba
> device based on ACPI table. Then we alter 8250/Kconfig to support
> AMD 8250 device and add quirk for AMD specific request.
> Secondly, since pl330 driver only provides dma engine for platform
> devices, we add an acpi dma engine interface.
> Then we add a new port type for AMD carrizo and set UART registers
> and dma rx size as hardware requirement.
> In the end, we make our IOMMU driver to support non-pci device, so
> UART DMA really works.
>

I commented on a few patches, thoughI might miss something in the rest.
Include me in Cc list next version.

> Thanks,
> Hongcheng
>
> Huang Rui (1):
>   ACPI: Add support for AMBA bus type
>
> Wan Zongshun (2):
>   Documentation: Add ivrs_acpihid kernel parameter description
>   iommu/amd: Add ACPI HID named devices IOMMU driver support
>
> Wang Hongcheng (6):
>   8250/Kconfig: add config option CONFIG_SERIAL_8250_AMD
>   ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config
>   dmaengine: pl330: add new items for pl330 private data
>   dmaengine: pl330: provide ACPI dmaengine interface
>   dmaengine:pl330: set segment_boundary_mask = 0cffffffff
>   Serial:8250: New Port Type PORT_AMD_8250
>
>  Documentation/kernel-parameters.txt |   7 ++
>  drivers/acpi/Makefile               |   1 +
>  drivers/acpi/acpi_amba.c            | 180 ++++++++++++++++++++++++++++++++++++
>  drivers/acpi/acpi_apd.c             |  89 +++++++++++++++---
>  drivers/dma/pl330.c                 |  61 ++++++++++--
>  drivers/iommu/amd_iommu.c           | 165 +++++++++++++++++++++++++++++----
>  drivers/iommu/amd_iommu_init.c      | 123 +++++++++++++++++++++++-
>  drivers/iommu/amd_iommu_types.h     |  11 +++
>  drivers/tty/serial/8250/8250_dw.c   |  16 ++++
>  drivers/tty/serial/8250/8250_port.c |   9 ++
>  drivers/tty/serial/8250/Kconfig     |   8 ++
>  include/linux/acpi.h                |  30 ++++++
>  include/linux/amba/pl330.h          |   4 +
>  include/linux/serial_8250.h         |   4 +
>  include/uapi/linux/serial_core.h    |   3 +-
>  include/uapi/linux/serial_reg.h     |   2 +
>  16 files changed, 673 insertions(+), 40 deletions(-)
>  create mode 100644 drivers/acpi/acpi_amba.c
>
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
With Best Regards,
Andy Shevchenko

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

end of thread, other threads:[~2015-12-13  2:32 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-04  3:24 [PATCH 0/9] 8250: AMD Carrizo UART PL300 DMA enablement Wang Hongcheng
2015-12-04  3:24 ` Wang Hongcheng
2015-12-04  3:24 ` [PATCH 1/9] ACPI: Add support for AMBA bus type Wang Hongcheng
2015-12-04  3:24   ` Wang Hongcheng
2015-12-04  8:50   ` Mika Westerberg
2015-12-04  9:17     ` Huang Rui
2015-12-04  9:17       ` Huang Rui
2015-12-04  9:42       ` Hanjun Guo
2015-12-04  9:42         ` Hanjun Guo
2015-12-04  9:59         ` G Gregory
2015-12-04 10:20           ` Huang Rui
2015-12-04 10:20             ` Huang Rui
2015-12-04 10:23             ` G Gregory
2015-12-04  3:24 ` [PATCH 2/9] 8250/Kconfig: add config option CONFIG_SERIAL_8250_AMD Wang Hongcheng
2015-12-04  3:24   ` Wang Hongcheng
2015-12-04 11:11   ` Borislav Petkov
2015-12-04  3:24 ` [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config Wang Hongcheng
2015-12-04  3:24   ` Wang Hongcheng
     [not found]   ` <1449199466-6081-4-git-send-email-annie.wang-5C7GfCeVMHo@public.gmane.org>
2015-12-04 12:56     ` kbuild test robot
2015-12-04 12:56       ` kbuild test robot
2015-12-04 13:16   ` Graeme Gregory
2015-12-11  6:57     ` Wang, Annie
     [not found]       ` <BLUPR12MB04339648B98F07977B6FA61F81EA0-7LeqcoF/hwrdEWIfrEWxYwdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2015-12-11  9:31         ` Vinod Koul
2015-12-11  9:31           ` Vinod Koul
2015-12-04  3:24 ` [PATCH 4/9] dmaengine: pl330: add new items for pl330 private data Wang Hongcheng
2015-12-04  3:24   ` Wang Hongcheng
2015-12-10  4:09   ` Vinod Koul
2015-12-10  6:38     ` Wang, Annie
     [not found]       ` <BLUPR12MB0433B81BB0AEB2D84505B55881E90-7LeqcoF/hwrdEWIfrEWxYwdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2015-12-11  9:29         ` Vinod Koul
2015-12-11  9:29           ` Vinod Koul
2015-12-11 13:56           ` Andy Shevchenko
2015-12-04  3:24 ` [PATCH 5/9] dmaengine: pl330: provide ACPI dmaengine interface Wang Hongcheng
2015-12-04  3:24   ` Wang Hongcheng
     [not found]   ` <1449199466-6081-6-git-send-email-annie.wang-5C7GfCeVMHo@public.gmane.org>
2015-12-13  2:21     ` Andy Shevchenko
2015-12-13  2:21       ` Andy Shevchenko
2015-12-04  3:24 ` [PATCH 6/9] dmaengine:pl330: set segment_boundary_mask = 0cffffffff Wang Hongcheng
2015-12-04  3:24   ` Wang Hongcheng
2015-12-04 14:59   ` Robin Murphy
2015-12-04  3:24 ` [PATCH 7/9] Serial:8250: New Port Type PORT_AMD_8250 Wang Hongcheng
2015-12-04  3:24   ` Wang Hongcheng
     [not found]   ` <1449199466-6081-8-git-send-email-annie.wang-5C7GfCeVMHo@public.gmane.org>
2015-12-13  2:30     ` Andy Shevchenko
2015-12-13  2:30       ` Andy Shevchenko
2015-12-04  3:24 ` [PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description Wang Hongcheng
2015-12-04  3:24   ` Wang Hongcheng
     [not found]   ` <1449199466-6081-9-git-send-email-annie.wang-5C7GfCeVMHo@public.gmane.org>
2015-12-04 12:21     ` Borislav Petkov
2015-12-04 12:21       ` Borislav Petkov
2015-12-04 13:19       ` Wan, Vincent
2015-12-04 13:19         ` Wan, Vincent
2015-12-04 14:38         ` Borislav Petkov
2015-12-04  3:24 ` [PATCH 9/9] iommu/amd: Add ACPI HID named devices IOMMU driver support Wang Hongcheng
2015-12-04  3:24   ` Wang Hongcheng
2015-12-13  2:32 ` [PATCH 0/9] 8250: AMD Carrizo UART PL300 DMA enablement Andy Shevchenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.