From patchwork Mon Jul 21 16:58:42 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Murali Karicheri X-Patchwork-Id: 4597661 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B33099F3B4 for ; Mon, 21 Jul 2014 17:02:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 83D6F200E6 for ; Mon, 21 Jul 2014 17:02:52 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id ECAA620170 for ; Mon, 21 Jul 2014 17:02:45 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1X9Gx3-0000aD-Ud; Mon, 21 Jul 2014 17:00:37 +0000 Received: from bear.ext.ti.com ([192.94.94.41]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1X9Gwc-0007kb-HN for linux-arm-kernel@lists.infradead.org; Mon, 21 Jul 2014 17:00:11 +0000 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id s6LGwm0J026165; Mon, 21 Jul 2014 11:58:48 -0500 Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id s6LGwmUh002676; Mon, 21 Jul 2014 11:58:48 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.3.174.1; Mon, 21 Jul 2014 11:58:48 -0500 Received: from localhost.localdomain (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id s6LGwik2008817; Mon, 21 Jul 2014 11:58:47 -0500 From: Murali Karicheri To: , , Subject: [PATCH v7 2/5] PCI: designware: refactor MSI code to work with v3.65 dw hardware Date: Mon, 21 Jul 2014 12:58:42 -0400 Message-ID: <1405961925-27248-3-git-send-email-m-karicheri2@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1405961925-27248-1-git-send-email-m-karicheri2@ti.com> References: <1405961925-27248-1-git-send-email-m-karicheri2@ti.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140721_100010_691618_FFB4A1A0 X-CRM114-Status: GOOD ( 17.97 ) X-Spam-Score: -5.0 (-----) Cc: Richard Zhu , Marek Vasut , Russell King , Pawel Moll , Arnd Bergmann , Ian Campbell , Randy Dunlap , Rob Herring , Kishon Vijay Abraham I , Bjorn Helgaas , Murali Karicheri , Kumar Gala , Grant Likely , Mark Rutland X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Keystone PCI controller is based on v3.65 version of the DW PCI h/w that implements MSI controller registers in application space compared to the newer version. This requires updates to the DW core API to support the PCI controller driver based on this old DW hardware. Add msi_irq_set()/clear() API functions to allow Set/Clear MSI IRQ enable bit in the application register. Also the old h/w uses MSI_IRQ register in application register space to raise MSI IRQ to the RC from EP. Current code uses the standard mechanism as per PCI spec. So add another API get_msi_data() to get the address of this register so that common code can be re-used on old h/w. Signed-off-by: Murali Karicheri Reviewed-by: Pratyush Anand Acked-by: Mohit Kumar Acked-by: Jingoo Han Acked-by: Santosh Shilimkar CC: Russell King CC: Grant Likely CC: Rob Herring CC: Bjorn Helgaas CC: Richard Zhu CC: Kishon Vijay Abraham I CC: Marek Vasut CC: Arnd Bergmann CC: Pawel Moll CC: Mark Rutland CC: Ian Campbell CC: Kumar Gala CC: Randy Dunlap CC: Grant Likely --- drivers/pci/host/pcie-designware.c | 50 ++++++++++++++++++++++++++---------- drivers/pci/host/pcie-designware.h | 3 +++ 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index d8f3af7..905941c 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -217,27 +217,47 @@ static int find_valid_pos0(struct pcie_port *pp, int msgvec, int pos, int *pos0) return 0; } +static void dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) +{ + unsigned int res, bit, val; + + res = (irq / 32) * 12; + bit = irq % 32; + dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); + val &= ~(1 << bit); + dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); +} + static void clear_irq_range(struct pcie_port *pp, unsigned int irq_base, unsigned int nvec, unsigned int pos) { - unsigned int i, res, bit, val; + unsigned int i; for (i = 0; i < nvec; i++) { irq_set_msi_desc_off(irq_base, i, NULL); clear_bit(pos + i, pp->msi_irq_in_use); /* Disable corresponding interrupt on MSI controller */ - res = ((pos + i) / 32) * 12; - bit = (pos + i) % 32; - dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); - val &= ~(1 << bit); - dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); + if (pp->ops->msi_clear_irq) + pp->ops->msi_clear_irq(pp, pos + i); + else + dw_pcie_msi_clear_irq(pp, pos + i); } } +static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) +{ + unsigned int res, bit, val; + + res = (irq / 32) * 12; + bit = irq % 32; + dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); + val |= 1 << bit; + dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); +} + static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) { - int res, bit, irq, pos0, pos1, i; - u32 val; + int irq, pos0, pos1, i; struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); if (!pp) { @@ -281,11 +301,10 @@ static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) } set_bit(pos0 + i, pp->msi_irq_in_use); /*Enable corresponding interrupt in MSI interrupt controller */ - res = ((pos0 + i) / 32) * 12; - bit = (pos0 + i) % 32; - dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val); - val |= 1 << bit; - dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val); + if (pp->ops->msi_set_irq) + pp->ops->msi_set_irq(pp, pos0 + i); + else + dw_pcie_msi_set_irq(pp, pos0 + i); } *pos = pos0; @@ -353,7 +372,10 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev, */ desc->msi_attrib.multiple = msgvec; - msg.address_lo = virt_to_phys((void *)pp->msi_data); + if (pp->ops->get_msi_data) + msg.address_lo = pp->ops->get_msi_data(pp); + else + msg.address_lo = virt_to_phys((void *)pp->msi_data); msg.address_hi = 0x0; msg.data = pos; write_msi_msg(irq, &msg); diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h index 8121901..387f69e 100644 --- a/drivers/pci/host/pcie-designware.h +++ b/drivers/pci/host/pcie-designware.h @@ -67,6 +67,9 @@ struct pcie_host_ops { unsigned int devfn, int where, int size, u32 val); int (*link_up)(struct pcie_port *pp); void (*host_init)(struct pcie_port *pp); + void (*msi_set_irq)(struct pcie_port *pp, int irq); + void (*msi_clear_irq)(struct pcie_port *pp, int irq); + u32 (*get_msi_data)(struct pcie_port *pp); }; int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val);