Hello Murali,

> -----Original Message-----
> From: Murali Karicheri [mailto:m-kariche...@ti.com]
> Sent: Wednesday, June 11, 2014 12:21 AM
> To: linux-arm-ker...@lists.infradead.org; linux-ker...@vger.kernel.org;
> linux-...@vger.kernel.org; devicetree@vger.kernel.org; linux-
> d...@vger.kernel.org
> Cc: Murali Karicheri; Santosh Shilimkar; Russell King; Grant Likely; Rob 
> Herring;
> Mohit KUMAR DCG; Jingoo Han; Bjorn Helgaas; Pratyush ANAND; Richard
> Zhu; Kishon Vijay Abraham I; Marek Vasut; Arnd Bergmann; Pawel Moll;
> Mark Rutland; Ian Campbell; Kumar Gala; Randy Dunlap
> Subject: [PATCH v2 4/8] PCI: designware: add msi controller functions for
> v3.65 hw
> 
> Add dw msi controller functions for v3.65 hw. This adds dw_v3_65_msi_chip
> and dw_v3_65_msi_domain_ops so that can be used on this version of the
> hw.
> This required since MSI irq registers reside in the application space for 
> v3.65
> hw. The functions are used by v3.65 dw pci core functions to support
> implementation of PCI controllers based on this hw version.
> 
> While at it, move the ATU hw specific variable and msi irq to a separate 
> struct
> inside a union and add another struct inside the union to hold dw v3.65
> specific variables.
> 
- Here also, pls look into Lucas work for MSI cleanup and then apply your 
changes:
[PATCH 0/4] proper multi MSI handling for designware host

Thanks
Mohit

> Signed-off-by: Murali Karicheri <m-kariche...@ti.com>
> 
> CC: Santosh Shilimkar <santosh.shilim...@ti.com>
> CC: Russell King <li...@arm.linux.org.uk>
> CC: Grant Likely <grant.lik...@linaro.org>
> CC: Rob Herring <robh...@kernel.org>
> CC: Mohit Kumar <mohit.ku...@st.com>
> CC: Jingoo Han <jg1....@samsung.com>
> CC: Bjorn Helgaas <bhelg...@google.com>
> CC: Pratyush Anand <pratyush.an...@st.com>
> CC: Richard Zhu <r65...@freescale.com>
> CC: Kishon Vijay Abraham I <kis...@ti.com>
> CC: Marek Vasut <ma...@denx.de>
> CC: Arnd Bergmann <a...@arndb.de>
> CC: Pawel Moll <pawel.m...@arm.com>
> CC: Mark Rutland <mark.rutl...@arm.com>
> CC: Ian Campbell <ijc+devicet...@hellion.org.uk>
> CC: Kumar Gala <ga...@codeaurora.org>
> CC: Randy Dunlap <rdun...@infradead.org>
> CC: Grant Likely <grant.lik...@linaro.org>
> 
> ---
>  drivers/pci/host/Kconfig            |    5 ++
>  drivers/pci/host/Makefile           |    1 +
>  drivers/pci/host/pci-dw-v3_65-msi.c |  149
> +++++++++++++++++++++++++++++++++++
>  drivers/pci/host/pci-dw-v3_65.h     |   20 +++++
>  drivers/pci/host/pcie-designware.h  |   21 +++--
>  5 files changed, 191 insertions(+), 5 deletions(-)  create mode 100644
> drivers/pci/host/pci-dw-v3_65-msi.c
>  create mode 100644 drivers/pci/host/pci-dw-v3_65.h
> 
> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index
> a6f67ec..2fcd9f9 100644
> --- a/drivers/pci/host/Kconfig
> +++ b/drivers/pci/host/Kconfig
> @@ -9,6 +9,11 @@ config PCI_MVEBU
>  config PCIE_DW
>       bool
> 
> +config PCI_DW_V3_65
> +     bool "Designware PCIe h/w v3.65"
> +     help
> +        Say Y here if the DW h/w version is 3.65
> +
>  config PCI_EXYNOS
>       bool "Samsung Exynos PCIe controller"
>       depends on SOC_EXYNOS5440
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index
> 13fb333..28af710 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -4,3 +4,4 @@ obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
>  obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
>  obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
>  obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
> +obj-$(CONFIG_PCI_DW_V3_65) += pci-dw-v3_65-msi.o
> diff --git a/drivers/pci/host/pci-dw-v3_65-msi.c b/drivers/pci/host/pci-dw-
> v3_65-msi.c
> new file mode 100644
> index 0000000..a26ffdd
> --- /dev/null
> +++ b/drivers/pci/host/pci-dw-v3_65-msi.c
> @@ -0,0 +1,149 @@
> +/*
> + * Designware(dw) MSI controller version 3.65
> + *
> + * Copyright (C) 2013-2014 Texas Instruments., Ltd.
> + *           http://www.ti.com
> + *
> + * Author: Murali Karicheri <m-kariche...@ti.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/of_irq.h>
> +#include <linux/kernel.h>
> +#include <linux/msi.h>
> +#include <linux/pci.h>
> +
> +#include "pcie-designware.h"
> +
> +#define MSI_IRQ                              0x054
> +#define MSI0_IRQ_STATUS                      0x104
> +#define MSI0_IRQ_ENABLE_SET          0x108
> +#define MSI0_IRQ_ENABLE_CLR          0x10c
> +#define IRQ_STATUS                   0x184
> +#define IRQ_EOI                         0x050
> +#define MSI_IRQ_OFFSET                       4
> +
> +static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) {
> +     return sys->private_data;
> +}
> +
> +static inline void update_reg_offset_bit_pos(u32 offset, u32 *reg_offset,
> +                                     u32 *bit_pos)
> +{
> +     *reg_offset = offset % 8;
> +     *bit_pos = offset >> 3;
> +}
> +
> +inline u32 dw_v3_65_get_msi_data(struct pcie_port *pp) {
> +     return pp->app.start + MSI_IRQ;
> +}
> +
> +void dw_v3_65_handle_msi_irq(struct pcie_port *pp, int offset) {
> +     u32 pending, vector;
> +     int src, virq;
> +
> +     pending = readl(pp->va_app_base + MSI0_IRQ_STATUS + (offset <<
> 4));
> +     /*
> +      * MSI0, Status bit 0-3 shows vectors 0, 8, 16, 24, MSI1 status bit
> +      * shows 1, 9, 17, 25 and so forth
> +      */
> +     for (src = 0; src < 4; src++) {
> +             if (BIT(src) & pending) {
> +                     vector = offset + (src << 3);
> +                     virq = irq_linear_revmap(pp->irq_domain, vector);
> +                     dev_dbg(pp->dev,
> +                             "irq: bit %d, vector %d, virq %d\n",
> +                              src, vector, virq);
> +                     generic_handle_irq(virq);
> +             }
> +     }
> +}
> +
> +static void dw_v3_65_msi_irq_ack(struct irq_data *d) {
> +     u32 offset, reg_offset, bit_pos;
> +     unsigned int irq = d->irq;
> +     struct msi_desc *msi;
> +     struct pcie_port *pp;
> +
> +     msi = irq_get_msi_desc(irq);
> +     pp = sys_to_pcie(msi->dev->bus->sysdata);
> +     offset = irq - irq_linear_revmap(pp->irq_domain, 0);
> +     update_reg_offset_bit_pos(offset, &reg_offset, &bit_pos);
> +
> +     writel(BIT(bit_pos),
> +             pp->va_app_base + MSI0_IRQ_STATUS + (reg_offset << 4));
> +     writel(reg_offset + MSI_IRQ_OFFSET, pp->va_app_base + IRQ_EOI);
> }
> +
> +static void dw_v3_65_msi_irq_mask(struct irq_data *d) {
> +     u32 offset, reg_offset, bit_pos;
> +     unsigned int irq = d->irq;
> +     struct msi_desc *msi;
> +     struct pcie_port *pp;
> +
> +     msi = irq_get_msi_desc(irq);
> +     pp = sys_to_pcie(msi->dev->bus->sysdata);
> +     offset = irq - irq_linear_revmap(pp->irq_domain, 0);
> +     update_reg_offset_bit_pos(offset, &reg_offset, &bit_pos);
> +
> +     /* mask the end point if PVM implemented */
> +     if (IS_ENABLED(CONFIG_PCI_MSI)) {
> +             if (msi->msi_attrib.maskbit)
> +                     mask_msi_irq(d);
> +     }
> +
> +     writel(BIT(bit_pos),
> +             pp->va_app_base + MSI0_IRQ_ENABLE_CLR + (reg_offset <<
> 4)); }
> +
> +static void dw_v3_65_msi_irq_unmask(struct irq_data *d) {
> +     u32 offset, reg_offset, bit_pos;
> +     unsigned int irq = d->irq;
> +     struct msi_desc *msi;
> +     struct pcie_port *pp;
> +
> +     msi = irq_get_msi_desc(irq);
> +     pp = sys_to_pcie(msi->dev->bus->sysdata);
> +     offset = irq - irq_linear_revmap(pp->irq_domain, 0);
> +     update_reg_offset_bit_pos(offset, &reg_offset, &bit_pos);
> +
> +     /* mask the end point if PVM implemented */
> +     if (IS_ENABLED(CONFIG_PCI_MSI)) {
> +             if (msi->msi_attrib.maskbit)
> +                     unmask_msi_irq(d);
> +     }
> +
> +     writel(BIT(bit_pos),
> +             pp->va_app_base + MSI0_IRQ_ENABLE_SET + (reg_offset <<
> 4)); }
> +
> +static struct irq_chip dw_v3_65_msi_chip = {
> +     .name = "PCI-DW-MSI-OLD",
> +     .irq_ack = dw_v3_65_msi_irq_ack,
> +     .irq_mask = dw_v3_65_msi_irq_mask,
> +     .irq_unmask = dw_v3_65_msi_irq_unmask, };
> +
> +static int dw_v3_65_msi_map(struct irq_domain *domain, unsigned int irq,
> +                     irq_hw_number_t hwirq)
> +{
> +     irq_set_chip_and_handler(irq, &dw_v3_65_msi_chip,
> handle_level_irq);
> +     irq_set_chip_data(irq, domain->host_data);
> +     set_irq_flags(irq, IRQF_VALID);
> +
> +     return 0;
> +}
> +
> +const struct irq_domain_ops dw_v3_65_msi_domain_ops = {
> +     .map = dw_v3_65_msi_map,
> +};
> diff --git a/drivers/pci/host/pci-dw-v3_65.h b/drivers/pci/host/pci-dw-
> v3_65.h new file mode 100644 index 0000000..689256a
> --- /dev/null
> +++ b/drivers/pci/host/pci-dw-v3_65.h
> @@ -0,0 +1,20 @@
> +/*
> + * Designware(dw) v3.65 controller common includes
> + *
> + * Copyright (C) 2013-2014 Texas Instruments., Ltd.
> + *           http://www.ti.com
> + *
> + * Author: Murali Karicheri <m-kariche...@ti.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.
> + */
> +
> +#define MAX_LEGACY_IRQS              4
> +
> +/* v3.65 specific MSI controller APIs/definitions */ extern const
> +struct irq_domain_ops dw_v3_65_msi_domain_ops; void
> +dw_v3_65_handle_msi_irq(struct pcie_port *pp, int offset);
> +u32 dw_v3_65_get_msi_data(struct pcie_port *pp);
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-
> designware.h
> index 3a6a6eb..05bb590 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -35,16 +35,27 @@ struct pcie_port {
>       struct device           *dev;
>       u8                      root_bus_nr;
>       void __iomem            *dbi_base;
> -     u64                     cfg0_base;
> -     void __iomem            *va_cfg0_base;
> -     u64                     cfg1_base;
> -     void __iomem            *va_cfg1_base;
>       /*
>        * v3.65 DW hw implements application register space for
>        * MSI and has no ATU view port
>        */
>  #define DW_V3_65             BIT(0)
>       u32                     version;
> +     union {
> +             /* New DW hw specific */
> +             struct {
> +                     u64                     cfg0_base;
> +                     void __iomem            *va_cfg0_base;
> +                     u64                     cfg1_base;
> +                     void __iomem            *va_cfg1_base;
> +                     int                     msi_irq;
> +             };
> +             /* v3.65 DW hw specific */
> +             struct  {
> +                     void __iomem            *va_app_base;
> +                     struct resource         app;
> +             };
> +     };
>       u64                     io_base;
>       u64                     mem_base;
>       spinlock_t              conf_lock;
> @@ -55,7 +66,7 @@ struct pcie_port {
>       int                     irq;
>       u32                     lanes;
>       struct pcie_host_ops    *ops;
> -     int                     msi_irq;
> +     /* msi irq domain */
>       struct irq_domain       *irq_domain;
>       unsigned long           msi_data;
>       DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
> --
> 1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to