Re: [PATCH 2/9] 8250/Kconfig: add config option CONFIG_SERIAL_8250_AMD

2015-12-04 Thread Borislav Petkov
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 
> ---
>  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.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description

2015-12-04 Thread Borislav Petkov
On Fri, Dec 04, 2015 at 11:24:25AM +0800, Wang Hongcheng wrote:
> From: Wan Zongshun 
> 
> Add ivrs_acpihid kernel parameter description,
> like ivrs_acpihid[00:14.5]=AMD0020:0.
> 
> Signed-off-by: Wan Zongshun 
> ---
>  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.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 6/9] dmaengine:pl330: set segment_boundary_mask = 0cffffffff

2015-12-04 Thread Robin Murphy

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 
Signed-off-by: Wang Hongcheng 
---
  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(>dev, "unable to set the seg size\n");

+   dev_info(>dev, "set the seg boundary\n");
+   ret = dma_set_seg_boundary(>dev, 0x);
+   if (ret)
+   dev_err(>dev, "unable to set the seg boundary\n");

dev_info(>dev,
 "Loaded driver for PL330 DMAC-%x\n", adev->periphid);



___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config

2015-12-04 Thread kbuild test robot
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, _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(_quirks, 0, sizeof(amba_quirks));
 > 145  setup_quirks(pdev, _quirks);
   146  
   147  amba_dev = acpi_create_amba_device(pdata->adev, 
0x00041330,
   148 4800,

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


.config.gz
Description: Binary data
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config

2015-12-04 Thread Graeme Gregory
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 
> ---
>  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(_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(>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(>dev), "DMA");
> + else
> + memcpy(amba_devname, dev_name(>dev),
> +strlen(dev_name(>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

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


RE: [PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description

2015-12-04 Thread Wan, Vincent
> > +   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.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/9] 8250/Kconfig: add config option CONFIG_SERIAL_8250_AMD

2015-12-04 Thread 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 
---
 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

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 1/9] ACPI: Add support for AMBA bus type

2015-12-04 Thread Wang Hongcheng
From: Huang Rui 

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 
Signed-off-by: Wang Hongcheng 
---
 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 000..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 
+ *  Wang Hongcheng 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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(_list);
+   count = acpi_dev_get_resources(adev, _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, _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(>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;
+

[PATCH 0/9] 8250: AMD Carrizo UART PL300 DMA enablement

2015-12-04 Thread 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 = 0c
  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

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description

2015-12-04 Thread Borislav Petkov
On Fri, Dec 04, 2015 at 01:19:35PM +, 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.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/9] ACPI: Add support for AMBA bus type

2015-12-04 Thread Huang Rui
On Fri, Dec 04, 2015 at 09:59:28AM +, G Gregory wrote:
> On 4 December 2015 at 09:42, Hanjun Guo  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 
> 
>  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
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 9/9] iommu/amd: Add ACPI HID named devices IOMMU driver support

2015-12-04 Thread Wang Hongcheng
From: Wan Zongshun 

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 
---
 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 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -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, _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, _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, _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 

Re: [PATCH 1/9] ACPI: Add support for AMBA bus type

2015-12-04 Thread G Gregory
On 4 December 2015 at 10:20, Huang Rui  wrote:
> On Fri, Dec 04, 2015 at 09:59:28AM +, G Gregory wrote:
>> On 4 December 2015 at 09:42, Hanjun Guo  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 
>> 
>>  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
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 8/9] Documentation: Add ivrs_acpihid kernel parameter description

2015-12-04 Thread Wang Hongcheng
From: Wan Zongshun 

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

Signed-off-by: Wan Zongshun 
---
 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

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/9] ACPI: Add support for AMBA bus type

2015-12-04 Thread Mika Westerberg
On Fri, Dec 04, 2015 at 11:24:18AM +0800, Wang Hongcheng wrote:
> From: Huang Rui 
> 
> 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
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 3/9] ACPI: add struct acpi_amba_quirk for AMD pl330 specific device config

2015-12-04 Thread 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 
---
 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(_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(>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(>dev), "DMA");
+   else
+   memcpy(amba_devname, dev_name(>dev),
+  strlen(dev_name(>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 
- * Wu, Jeff 
+ *  Jeff Wu <15618388...@163.com>
+ * Wang Hongcheng 
  *
  * 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 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include "internal.h"
 
@@ -31,14 +36,15 @@ struct apd_private_data;
 #define ACPI_APD_PMBIT(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 

[PATCH 5/9] dmaengine: pl330: provide ACPI dmaengine interface

2015-12-04 Thread 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 
---
 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))
 
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(>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(>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(>dev)) {
+   ret = acpi_dma_controller_register(>dev,
+  acpi_dma_pl330_xlate, pl330);
+   if (ret) {
+   dev_err(>dev,
+   "unable to register DMA to the generic ACPI DMA 
helpers\n");
+   }
+   }
+
adev->dev.dma_parms = >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

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/9] ACPI: Add support for AMBA bus type

2015-12-04 Thread G Gregory
On 4 December 2015 at 09:42, Hanjun Guo  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 

 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
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 4/9] dmaengine: pl330: add new items for pl330 private data

2015-12-04 Thread 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 
---
 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 
 #include 
 #include 
+#include 
 #include 
 
 #include "internal.h"
@@ -35,6 +36,16 @@ struct apd_private_data;
 #define ACPI_APD_SYSFS BIT(0)
 #define ACPI_APD_PMBIT(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,
   4800,
-  NULL,
+  _pl330,
   _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 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 
@@ -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 = >res;
pl330->base = devm_ioremap_resource(>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(>dev, irq,
-  pl330_irq_handler, 0,
+  pl330_irq_handler, pl330->flags,
   dev_name(>dev), pl330);
if (ret)
return ret;
@@ -2870,7 +2877,7 @@ pl330_probe(struct amba_device *adev, const struct 
amba_id *id)
list_add_tail(>chan.device_node, >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(>dev,
-   "Loaded driver for PL330 DMAC-%x\n", adev->periphid);
+"Loaded driver for PL330 DMAC-%x\n", adev->periphid);
dev_info(>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(>dev);
pm_runtime_use_autosuspend(>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

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 6/9] dmaengine:pl330: set segment_boundary_mask = 0cffffffff

2015-12-04 Thread Wang Hongcheng
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 
Signed-off-by: Wang Hongcheng 
---
 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(>dev, "unable to set the seg size\n");
 
+   dev_info(>dev, "set the seg boundary\n");
+   ret = dma_set_seg_boundary(>dev, 0x);
+   if (ret)
+   dev_err(>dev, "unable to set the seg boundary\n");
 
dev_info(>dev,
 "Loaded driver for PL330 DMAC-%x\n", adev->periphid);
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 5/5] iommu/io-pgtable: Add ARMv7 short descriptor support

2015-12-04 Thread Robin Murphy
Add a nearly-complete ARMv7 short descriptor implementation, omitting
only a few legacy and CPU-centric aspects which shouldn't be necessary
for IOMMU API use anyway.

Signed-off-by: Yong Wu 
Signed-off-by: Robin Murphy 
---
 drivers/iommu/Kconfig  |  19 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/io-pgtable-arm-v7s.c | 836 +
 drivers/iommu/io-pgtable.c |   3 +
 drivers/iommu/io-pgtable.h |  14 +-
 5 files changed, 872 insertions(+), 1 deletion(-)
 create mode 100644 drivers/iommu/io-pgtable-arm-v7s.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index b9094e9..b591022 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -39,6 +39,25 @@ config IOMMU_IO_PGTABLE_LPAE_SELFTEST
 
  If unsure, say N here.
 
+config IOMMU_IO_PGTABLE_ARMV7S
+   bool "ARMv7/v8 Short Descriptor Format"
+   select IOMMU_IO_PGTABLE
+   depends on HAS_DMA && (ARM || ARM64 || COMPILE_TEST)
+   help
+ Enable support for the ARM Short-descriptor pagetable format.
+ This supports 32-bit virtual and physical addresses mapped using
+ 2-level tables with 4KB pages/1MB sections, and contiguous entries
+ for 64KB pages/16MB supersections if indicated by the IOMMU driver.
+
+config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
+   bool "ARMv7s selftests"
+   depends on IOMMU_IO_PGTABLE_ARMV7S
+   help
+ Enable self-tests for ARMv7s page table allocator. This performs
+ a series of page-table consistency checks during boot.
+
+ If unsure, say N here.
+
 endmenu
 
 config IOMMU_IOVA
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 68faca02..47f11d9 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
+obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
 obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
new file mode 100644
index 000..52e85a0
--- /dev/null
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -0,0 +1,836 @@
+/*
+ * CPU-agnostic ARM page table allocator.
+ *
+ * ARMv7 Short-descriptor format, supporting
+ * - Basic memory attributes
+ * - Simplified access permissions (AP[2:1] model)
+ * - Backwards-compatible TEX remap
+ * - Large pages/supersections (if indicated by the caller)
+ *
+ * Not supporting:
+ * - Legacy access permissions (AP[2:0] model)
+ *
+ * Almost certainly never supporting:
+ * - PXN
+ * - Domains
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ *
+ * Copyright (C) 2014-2015 ARM Limited
+ * Copyright (c) 2014-2015 MediaTek Inc.
+ */
+
+#define pr_fmt(fmt)"arm-v7s io-pgtable: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "io-pgtable.h"
+
+/* Struct accessors */
+#define io_pgtable_to_data(x)  \
+   container_of((x), struct arm_v7s_io_pgtable, iop)
+
+#define io_pgtable_ops_to_data(x)  \
+   io_pgtable_to_data(io_pgtable_ops_to_pgtable(x))
+
+/*
+ * We have 32 bits total; 12 bits resolved at level 1, 8 bits at level 2,
+ * and 12 bits in a page. With some carefully-chosen coefficients we can
+ * hide the ugly inconsistencies behind these macros and at least let the
+ * rest of the code pretend to be somewhat sane.
+ */
+#define ARM_V7S_ADDR_BITS  32
+#define _ARM_V7S_LVL_BITS(lvl) (16 - (lvl) * 4)
+#define ARM_V7S_LVL_SHIFT(lvl) (ARM_V7S_ADDR_BITS - (4 + 8 * (lvl)))
+#define ARM_V7S_TABLE_SHIFT10
+
+#define ARM_V7S_PTES_PER_LVL(lvl)  (1 << _ARM_V7S_LVL_BITS(lvl))
+#define ARM_V7S_TABLE_SIZE(lvl)
\
+   (ARM_V7S_PTES_PER_LVL(lvl) * sizeof(arm_v7s_iopte))
+
+#define ARM_V7S_BLOCK_SIZE(lvl)(1UL << ARM_V7S_LVL_SHIFT(lvl))
+#define ARM_V7S_LVL_MASK(lvl)  ((u32)(~0U << ARM_V7S_LVL_SHIFT(lvl)))
+#define ARM_V7S_TABLE_MASK ((u32)(~0U << ARM_V7S_TABLE_SHIFT))
+#define _ARM_V7S_IDX_MASK(lvl) 

[PATCH 0/5] io-pgtable fixes + ARM short-descriptor format

2015-12-04 Thread Robin Murphy
This has been tested on an MMU-500 Fast Model, with the ARM SMMU driver
hacked up to force short-descriptor at stage 1 - doing it properly needs
more work to decouple the context format from the kernel bit-ness. Since
I didn't want to delay getting this lot posted, that can come later.

Thanks,
Robin.

Robin Murphy (5):
  iommu/io-pgtable-arm: Avoid dereferencing bogus PTEs
  iommu/io-pgtable: Indicate granule for TLB maintenance
  iommu/arm-smmu: Invalidate TLBs properly
  iommu/io-pgtable: Make io_pgtable_ops_to_pgtable() macro common
  iommu/io-pgtable: Add ARMv7 short descriptor support

 drivers/iommu/Kconfig  |  19 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/arm-smmu-v3.c|   2 +-
 drivers/iommu/arm-smmu.c   |  21 +-
 drivers/iommu/io-pgtable-arm-v7s.c | 836 +
 drivers/iommu/io-pgtable-arm.c |  38 +-
 drivers/iommu/io-pgtable.c |   3 +
 drivers/iommu/io-pgtable.h |  20 +-
 drivers/iommu/ipmmu-vmsa.c |   4 +-
 9 files changed, 916 insertions(+), 28 deletions(-)
 create mode 100644 drivers/iommu/io-pgtable-arm-v7s.c

-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 4/5] iommu/io-pgtable: Make io_pgtable_ops_to_pgtable() macro common

2015-12-04 Thread Robin Murphy
There is no need to keep a useful accessor for a public structure hidden
away in a private implementation. Move it out alongside the structure
definition so that other implementations may reuse it.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/io-pgtable-arm.c | 3 ---
 drivers/iommu/io-pgtable.h | 2 ++
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 9088d27..1619681 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -38,9 +38,6 @@
 #define io_pgtable_to_data(x)  \
container_of((x), struct arm_lpae_io_pgtable, iop)
 
-#define io_pgtable_ops_to_pgtable(x)   \
-   container_of((x), struct io_pgtable, ops)
-
 #define io_pgtable_ops_to_data(x)  \
io_pgtable_to_data(io_pgtable_ops_to_pgtable(x))
 
diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
index 2e18469..36673c8 100644
--- a/drivers/iommu/io-pgtable.h
+++ b/drivers/iommu/io-pgtable.h
@@ -131,6 +131,8 @@ struct io_pgtable {
struct io_pgtable_ops   ops;
 };
 
+#define io_pgtable_ops_to_pgtable(x) container_of((x), struct io_pgtable, ops)
+
 /**
  * struct io_pgtable_init_fns - Alloc/free a set of page tables for a
  *  particular format.
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/5] iommu/io-pgtable: Indicate granule for TLB maintenance

2015-12-04 Thread Robin Murphy
IOMMU hardware with range-based TLB maintenance commands can work
happily with the iova and size arguments passed via the tlb_add_flush
callback, but for IOMMUs which require separate commands per entry in
the range, it is not straightforward to infer the necessary granularity
when it comes to issuing the actual commands.

Add an additional argument indicating the granularity for the benefit
of drivers needing to know, and update the ARM LPAE code appropriately
(for non-leaf invalidations we currently just assume the worst-case
page granularity rather than walking the table to check).

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu-v3.c|  2 +-
 drivers/iommu/arm-smmu.c   |  2 +-
 drivers/iommu/io-pgtable-arm.c | 27 +++
 drivers/iommu/io-pgtable.h |  4 ++--
 drivers/iommu/ipmmu-vmsa.c |  4 ++--
 5 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 4e5118a..c302b65 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1335,7 +1335,7 @@ static void arm_smmu_tlb_inv_context(void *cookie)
 }
 
 static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
- bool leaf, void *cookie)
+ size_t granule, bool leaf, void 
*cookie)
 {
struct arm_smmu_domain *smmu_domain = cookie;
struct arm_smmu_device *smmu = smmu_domain->smmu;
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 47dc7a7..601e3dd 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -582,7 +582,7 @@ static void arm_smmu_tlb_inv_context(void *cookie)
 }
 
 static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
- bool leaf, void *cookie)
+ size_t granule, bool leaf, void 
*cookie)
 {
struct arm_smmu_domain *smmu_domain = cookie;
struct arm_smmu_cfg *cfg = _domain->cfg;
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 366a354..9088d27 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -58,8 +58,10 @@
d)->levels - ((l) - ARM_LPAE_START_LVL(d) + 1)) \
  * (d)->bits_per_level) + (d)->pg_shift)
 
+#define ARM_LPAE_GRANULE(d)(1UL << (d)->pg_shift)
+
 #define ARM_LPAE_PAGES_PER_PGD(d)  \
-   DIV_ROUND_UP((d)->pgd_size, 1UL << (d)->pg_shift)
+   DIV_ROUND_UP((d)->pgd_size, ARM_LPAE_GRANULE(d))
 
 /*
  * Calculate the index at level l used to map virtual address a using the
@@ -169,7 +171,7 @@
 /* IOPTE accessors */
 #define iopte_deref(pte,d) \
(__va((pte) & ((1ULL << ARM_LPAE_MAX_ADDR_BITS) - 1)\
-   & ~((1ULL << (d)->pg_shift) - 1)))
+   & ~(ARM_LPAE_GRANULE(d) - 1)))
 
 #define iopte_type(pte,l)  \
(((pte) >> ARM_LPAE_PTE_TYPE_SHIFT) & ARM_LPAE_PTE_TYPE_MASK)
@@ -326,7 +328,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, 
unsigned long iova,
/* Grab a pointer to the next level */
pte = *ptep;
if (!pte) {
-   cptep = __arm_lpae_alloc_pages(1UL << data->pg_shift,
+   cptep = __arm_lpae_alloc_pages(ARM_LPAE_GRANULE(data),
   GFP_ATOMIC, cfg);
if (!cptep)
return -ENOMEM;
@@ -412,7 +414,7 @@ static void __arm_lpae_free_pgtable(struct 
arm_lpae_io_pgtable *data, int lvl,
if (lvl == ARM_LPAE_START_LVL(data))
table_size = data->pgd_size;
else
-   table_size = 1UL << data->pg_shift;
+   table_size = ARM_LPAE_GRANULE(data);
 
start = ptep;
end = (void *)ptep + table_size;
@@ -473,7 +475,7 @@ static int arm_lpae_split_blk_unmap(struct 
arm_lpae_io_pgtable *data,
 
__arm_lpae_set_pte(ptep, table, cfg);
iova &= ~(blk_size - 1);
-   cfg->tlb->tlb_add_flush(iova, blk_size, true, data->iop.cookie);
+   cfg->tlb->tlb_add_flush(iova, blk_size, blk_size, true, 
data->iop.cookie);
return size;
 }
 
@@ -501,12 +503,13 @@ static int __arm_lpae_unmap(struct arm_lpae_io_pgtable 
*data,
 
if (!iopte_leaf(pte, lvl)) {
/* Also flush any partial walks */
-   tlb->tlb_add_flush(iova, size, false, cookie);
+   tlb->tlb_add_flush(iova, size, ARM_LPAE_GRANULE(data),
+  false, cookie);
tlb->tlb_sync(cookie);
ptep = iopte_deref(pte, data);
__arm_lpae_free_pgtable(data, lvl + 1, ptep);
} else {
-   tlb->tlb_add_flush(iova, size, true, cookie);

[PATCH 1/5] iommu/io-pgtable-arm: Avoid dereferencing bogus PTEs

2015-12-04 Thread Robin Murphy
In the case of corrupted page tables, or when an invalid size is given,
__arm_lpae_unmap() may recurse beyond the maximum number of levels.
Unfortunately the detection of this error condition only happens *after*
calculating a nonsense offset from something which might not be a valid
table pointer and dereferencing that to see if it is a valid PTE.

Make things a little more robust by checking the level is valid before
doing anything which depends on it being so.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/io-pgtable-arm.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 7df9777..366a354 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -486,11 +486,13 @@ static int __arm_lpae_unmap(struct arm_lpae_io_pgtable 
*data,
void *cookie = data->iop.cookie;
size_t blk_size = ARM_LPAE_BLOCK_SIZE(lvl, data);
 
+   /* Something went horribly wrong and we ran out of page table */
+   if (WARN_ON(lvl == ARM_LPAE_MAX_LEVELS))
+   return 0;
+
ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
pte = *ptep;
-
-   /* Something went horribly wrong and we ran out of page table */
-   if (WARN_ON(!pte || (lvl == ARM_LPAE_MAX_LEVELS)))
+   if (WARN_ON(!pte))
return 0;
 
/* If the size matches this level, we're in the right place */
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 3/5] iommu/arm-smmu: Invalidate TLBs properly

2015-12-04 Thread Robin Murphy
When invalidating an IOVA range potentially spanning multiple pages,
such as when removing an entire intermediate-level table, we currently
only issue an invalidation for the first IOVA of that range. Since the
architecture specifies that address-based TLB maintenance operations
target a single entry, an SMMU could feasibly retain live entries for
subsequent pages within that unmapped range, which is not good.

Make sure we hit every possible entry by iterating over the whole range
at the granularity provided by the pagetable implementation.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 19 ---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 601e3dd..f1d6fa7 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -597,12 +597,20 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long 
iova, size_t size,
if (!IS_ENABLED(CONFIG_64BIT) || smmu->version == ARM_SMMU_V1) {
iova &= ~12UL;
iova |= ARM_SMMU_CB_ASID(cfg);
-   writel_relaxed(iova, reg);
+   while (size) {
+   writel_relaxed(iova, reg);
+   size -= granule;
+   iova += granule;
+   }
 #ifdef CONFIG_64BIT
} else {
iova >>= 12;
iova |= (u64)ARM_SMMU_CB_ASID(cfg) << 48;
-   writeq_relaxed(iova, reg);
+   while (size) {
+   writeq_relaxed(iova, reg);
+   size -= granule;
+   iova += granule >> 12;
+   }
 #endif
}
 #ifdef CONFIG_64BIT
@@ -610,7 +618,12 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long 
iova, size_t size,
reg = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
reg += leaf ? ARM_SMMU_CB_S2_TLBIIPAS2L :
  ARM_SMMU_CB_S2_TLBIIPAS2;
-   writeq_relaxed(iova >> 12, reg);
+   iova >>= 12;
+   while (size) {
+   writeq_relaxed(iova, reg);
+   size -= granule;
+   iova += granule >> 12;
+   }
 #endif
} else {
reg = ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_TLBIVMID;
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu