From patchwork Tue Nov 6 13:21:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Z.Q. Hou" X-Patchwork-Id: 993714 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=nxp.com header.i=@nxp.com header.b="fo172d22"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42q9Dr1w1pz9sDb for ; Wed, 7 Nov 2018 00:21:48 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387922AbeKFWqm (ORCPT ); Tue, 6 Nov 2018 17:46:42 -0500 Received: from mail-db5eur01on0082.outbound.protection.outlook.com ([104.47.2.82]:27088 "EHLO EUR01-DB5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2388180AbeKFWql (ORCPT ); Tue, 6 Nov 2018 17:46:41 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=mVgDtGVx6qdNsZHy7LpnTvW7755nFc/ty1myaR0GhoI=; b=fo172d22SGx2tyGKTbEsK81aRiGvhgqJgrTKLPgMLpVYUT8Y7gpfJ+bf120QTnUEu0P66CLwWyPv7dUdFMnF99qHmFsoNzxBC6NVC9IHgDCh4HE1eZFNIN4CFQo8jKg2hVLquLGxsjmI8zNM9yj8WF9Lfxm1CXpZxXr4yMoKtME= Received: from DB5PR04MB1221.eurprd04.prod.outlook.com (10.162.155.27) by DB5PR04MB2119.eurprd04.prod.outlook.com (10.166.172.136) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1294.28; Tue, 6 Nov 2018 13:21:25 +0000 Received: from DB5PR04MB1221.eurprd04.prod.outlook.com ([fe80::6c36:f4cb:26c2:e8cb]) by DB5PR04MB1221.eurprd04.prod.outlook.com ([fe80::6c36:f4cb:26c2:e8cb%2]) with mapi id 15.20.1273.035; Tue, 6 Nov 2018 13:21:25 +0000 From: "Z.q. Hou" To: "linux-pci@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "devicetree@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "bhelgaas@google.com" , "robh+dt@kernel.org" , "mark.rutland@arm.com" , "l.subrahmanya@mobiveil.co.in" , "shawnguo@kernel.org" , Leo Li , "lorenzo.pieralisi@arm.com" CC: Mingkai Hu , "M.h. Lian" , Xiaowei Bao , "Z.q. Hou" Subject: [PATCH 22/23] PCI: mobiveil: add PCIe RC driver for NXP LX series SoCs Thread-Topic: [PATCH 22/23] PCI: mobiveil: add PCIe RC driver for NXP LX series SoCs Thread-Index: AQHUddOeWH2W17CrSk6lzc/1cOUlfw== Date: Tue, 6 Nov 2018 13:21:25 +0000 Message-ID: <20181106131807.29951-23-Zhiqiang.Hou@nxp.com> References: <20181106131807.29951-1-Zhiqiang.Hou@nxp.com> In-Reply-To: <20181106131807.29951-1-Zhiqiang.Hou@nxp.com> Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: HK0PR03CA0008.apcprd03.prod.outlook.com (2603:1096:203:2e::20) To DB5PR04MB1221.eurprd04.prod.outlook.com (2a01:111:e400:51c2::27) authentication-results: spf=none (sender IP is ) smtp.mailfrom=zhiqiang.hou@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [119.31.174.73] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB5PR04MB2119; 6:ZocHzOUaHXh2dRmQaIQ8XHT5+YXfvoJWLP/dEpgQ91jGwquse7wOEAFSBBHb3pzfkcRGOM9Vw+yqyTOGs7ckjGjoG6pESe/RulM1cNVYtAjrI2+KwUYT4Fy+PHB11cpc+Kprr5F7U32tIlmR4YhzvOWc3sHV4pXd4RO7oCYEAwLwe3jhE3KFT0FjlDXASrPgbRUmgLXvq+NbKXn/CZqFSTU3Iap6amYEBi8d442cSwNVO11dDmyf6CraJM1OnLaJNEhg0RoqwdAW3ICRshJCxTaH8ufcquFyRIG2n85P4UIvmTxBWLPHV6X00J/TysShQV2V0PkNb7hcBTNqNiLYnp7HcjTr4Ppl6QQLWqtHkIzEQBcCM1q1v4/c6+Q5nBgvXbZwurnsGLEHEZtWQ80mlsz2neoMJPFfLGG0IKMkrEh2k+xLjJzQDQR5AzdUZX6FCQfKWDYlUmbrcRK8XlyfcA==; 5:PJv4XnJ+L+jOV+xLkRvCNHe4QFl8NdeJ2QMSyWr0jLvR0+eyHlml2g2XBcfTd1SWYoUGGFORYiOmEFWZJjDY/caGvmTDmaGSuY+/BZ87kaOW78Msx3NM0b6ZoB6eelVsYeZ5tXifGLlhLnOOQwgSYU3eQnf+5glut9yr39YaQ7I=; 7:qFlD4peB/dSF62vaKMwlpLq3YMfWYf8UpW6qPHw6slNQZHJozcj3T/Mz/KnHqgddjMirtdgvpNwboOq9GtnnMI2UtFEDszEwAozAmYf3wBiuc8dIsc1jZAD5KQ/NhKTCY6XL+t2E8QKjIRxTHF+A1Q== x-ms-office365-filtering-correlation-id: 76891e7d-26af-4977-740f-08d643eac04c x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:DB5PR04MB2119; x-ms-traffictypediagnostic: DB5PR04MB2119: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(185117386973197); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(93006095)(93001095)(3231382)(944501410)(52105095)(10201501046)(3002001)(6055026)(148016)(149066)(150057)(6041310)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123562045)(20161123558120)(201708071742011)(7699051)(76991095); SRVR:DB5PR04MB2119; BCL:0; PCL:0; RULEID:; SRVR:DB5PR04MB2119; x-forefront-prvs: 0848C1A6AA x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(6029001)(346002)(376002)(396003)(136003)(39860400002)(366004)(189003)(199004)(81156014)(99286004)(2201001)(8936002)(575784001)(86362001)(6486002)(68736007)(6436002)(5660300001)(478600001)(53936002)(6512007)(4326008)(25786009)(36756003)(14454004)(54906003)(186003)(316002)(110136005)(2906002)(2900100001)(1076002)(3846002)(6116002)(81166006)(8676002)(7416002)(256004)(14444005)(446003)(11346002)(486006)(476003)(2616005)(7736002)(305945005)(71190400001)(71200400001)(66066001)(97736004)(76176011)(52116002)(102836004)(106356001)(26005)(2501003)(105586002)(386003)(6506007)(921003)(1121003); DIR:OUT; SFP:1101; SCL:1; SRVR:DB5PR04MB2119; H:DB5PR04MB1221.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: FV08fU5/3Qm9eSVUpY/CeEaQgsDdlNNgwE3R+4QEwFOyqBqWfK4/nSKzfsCTtVqKv9WV7UtUb7bRqND2ZH8n7bro2rdVXsEEISim3lX9wzMmn0LEgEOnw/80ZjG0oaD1eUyNcTJBdmirip0K3JbuL8/p5KbU/sMM901swW1eD0UeWP9W0xXJmMph8CDi2Skqtfei7NIWwsh8NtMXMo51MGYmBZlGt+d2psj8jOhb7eUg+R+bnwd88zl21qXLkCD7mOKRANpv3vHcFSkyoP3zZ6GKqFM0q5rJQO/tplr0UKIoptz91qMlG7w00p7ZRmiVxNuMQEDgLDXIJ3WBayu8YeAJxFvf/YgWq/W45XT3NZg= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-ID: MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 76891e7d-26af-4977-740f-08d643eac04c X-MS-Exchange-CrossTenant-originalarrivaltime: 06 Nov 2018 13:21:25.2022 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB5PR04MB2119 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Hou Zhiqiang This PCIe controller is based on the Mobiveil GPEX IP, which is compatible with the PCI Express™ Base Specification, Revision 4.0. Signed-off-by: Hou Zhiqiang --- drivers/pci/controller/mobiveil/Kconfig | 10 + drivers/pci/controller/mobiveil/Makefile | 1 + drivers/pci/controller/mobiveil/pci-lx.c | 222 ++++++++++++++++++ .../controller/mobiveil/pcie-mobiveil-host.c | 5 +- .../pci/controller/mobiveil/pcie-mobiveil.h | 15 +- 5 files changed, 249 insertions(+), 4 deletions(-) create mode 100644 drivers/pci/controller/mobiveil/pci-lx.c diff --git a/drivers/pci/controller/mobiveil/Kconfig b/drivers/pci/controller/mobiveil/Kconfig index 64343c07bfed..1025448f6d0c 100644 --- a/drivers/pci/controller/mobiveil/Kconfig +++ b/drivers/pci/controller/mobiveil/Kconfig @@ -21,4 +21,14 @@ config PCIE_MOBIVEIL_PLAT Soft IP. It has up to 8 outbound and inbound windows for address translation and it is a PCIe Gen4 IP. +config PCI_LX + bool "Freescale LX PCIe controller" + depends on PCI + depends on OF && (ARM64 || ARCH_LAYERSCAPE) + depends on PCI_MSI_IRQ_DOMAIN + select PCIE_MOBIVEIL_HOST + help + Say Y here if you want PCIe controller support on LX SoCs. + The PCIe controller can work in RC or EP mode according to + RCW[HOST_AGT_PEX] setting. endmenu diff --git a/drivers/pci/controller/mobiveil/Makefile b/drivers/pci/controller/mobiveil/Makefile index 9fb6d1c6504d..e5318a334149 100644 --- a/drivers/pci/controller/mobiveil/Makefile +++ b/drivers/pci/controller/mobiveil/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o obj-$(CONFIG_PCIE_MOBIVEIL_HOST) += pcie-mobiveil-host.o obj-$(CONFIG_PCIE_MOBIVEIL_PLAT) += pcie-mobiveil-plat.o +obj-$(CONFIG_PCI_LX) += pci-lx.o diff --git a/drivers/pci/controller/mobiveil/pci-lx.c b/drivers/pci/controller/mobiveil/pci-lx.c new file mode 100644 index 000000000000..5308255dc725 --- /dev/null +++ b/drivers/pci/controller/mobiveil/pci-lx.c @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PCIe host controller driver for NXP LX SoCs + * + * Copyright 2018 NXP + * + * Author: Zhiqiang Hou + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcie-mobiveil.h" + +/* LUT and PF control registers */ +#define PCIE_LUT_OFF (0x80000) +#define PCIE_PF_OFF (0xc0000) +#define PCIE_PF_INT_STAT (0x18) +#define PF_INT_STAT_PABRST (31) + +#define PCIE_PF_DBG (0x7fc) +#define PF_DBG_LTSSM_MASK (0x3f) +#define PF_DBG_WE (31) +#define PF_DBG_PABR (27) + +#define LX_PCIE_LTSSM_L0 0x2d /* L0 state */ + +struct lx_pcie { + struct mobiveil_pcie *pci; + int irq; +}; + +#define to_lx_pcie(x) platform_get_drvdata((x)->pdev) + +static inline u32 lx_pcie_lut_readl(struct lx_pcie *pcie, u32 off) +{ + return ioread32(pcie->pci->csr_axi_slave_base + PCIE_LUT_OFF + off); +} + +static inline void lx_pcie_lut_writel(struct lx_pcie *pcie, u32 off, u32 val) +{ + iowrite32(val, pcie->pci->csr_axi_slave_base + PCIE_LUT_OFF + off); +} + +static inline u32 lx_pcie_pf_readl(struct lx_pcie *pcie, u32 off) +{ + return ioread32(pcie->pci->csr_axi_slave_base + PCIE_PF_OFF + off); +} + +static inline void lx_pcie_pf_writel(struct lx_pcie *pcie, u32 off, u32 val) +{ + iowrite32(val, pcie->pci->csr_axi_slave_base + PCIE_PF_OFF + off); +} + +static bool lx_pcie_is_bridge(struct lx_pcie *pcie) +{ + struct mobiveil_pcie *mv_pci = pcie->pci; + u32 header_type; + + header_type = csr_readb(mv_pci, PCI_HEADER_TYPE); + header_type &= 0x7f; + + return header_type == PCI_HEADER_TYPE_BRIDGE; +} + +static int lx_pcie_link_up(struct mobiveil_pcie *pci) +{ + struct lx_pcie *pcie = to_lx_pcie(pci); + u32 state; + + state = lx_pcie_pf_readl(pcie, PCIE_PF_DBG); + state = state & PF_DBG_LTSSM_MASK; + + if (state == LX_PCIE_LTSSM_L0) + return 1; + + return 0; +} + +static int lx_pcie_interrupt_init(struct mobiveil_pcie *pcie) +{ + return 0; +} + +static struct mobiveil_rp_ops lx_pcie_rp_ops = { + .interrupt_init = lx_pcie_interrupt_init, +}; + +static const struct mobiveil_pab_ops lx_pcie_pab_ops = { + .link_up = lx_pcie_link_up, +}; + +static const struct of_device_id lx_pcie_of_match[] = { + { .compatible = "fsl,lx2160a-pcie", }, + { }, +}; + +static void lx_pcie_reinit_hw(struct lx_pcie *pcie) +{ + struct mobiveil_pcie *mv_pci = pcie->pci; + u32 val, act_stat; + + /* Poll for pab_csb_reset to clear , PAB activity to set */ + do { + val = lx_pcie_pf_readl(pcie, PCIE_PF_INT_STAT); + act_stat = csr_readl(mv_pci, PAB_ACTIVITY_STAT); + + } while (((val & (1 << PF_INT_STAT_PABRST)) == 0) || act_stat); + + while (!lx_pcie_link_up(mv_pci)) + ; + + /* clear PEX_RESET bit in PEX_PF0_DBG register */ + val = lx_pcie_pf_readl(pcie, PCIE_PF_DBG); + val |= 1 << PF_DBG_WE; + lx_pcie_pf_writel(pcie, PCIE_PF_DBG, val); + + val = lx_pcie_pf_readl(pcie, PCIE_PF_DBG); + val |= 1 << PF_DBG_PABR; + lx_pcie_pf_writel(pcie, PCIE_PF_DBG, val); + + val = lx_pcie_pf_readl(pcie, PCIE_PF_DBG); + val &= ~(1 << PF_DBG_WE); + lx_pcie_pf_writel(pcie, PCIE_PF_DBG, val); + + mobiveil_host_init(mv_pci, true); +} + +static irqreturn_t lx_pcie_handler(int irq, void *dev_id) +{ + struct lx_pcie *pcie = (struct lx_pcie *)dev_id; + struct mobiveil_pcie *mv_pci = pcie->pci; + u32 val; + u16 ctrl; + + val = csr_readl(mv_pci, PAB_INTP_AMBA_MISC_STAT); + if (!val) + return IRQ_NONE; + + if (val & PAB_INTP_RESET) { + ctrl = csr_readw(mv_pci, PCI_BRIDGE_CONTROL); + ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; + csr_writew(mv_pci, ctrl, PCI_BRIDGE_CONTROL); + lx_pcie_reinit_hw(pcie); + } + + csr_writel(mv_pci, val, PAB_INTP_AMBA_MISC_STAT); + + return IRQ_HANDLED; +} + +static int __init lx_pcie_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mobiveil_pcie *mv_pci; + struct lx_pcie *pcie; + struct device_node *np = dev->of_node; + int ret; + + if (!of_parse_phandle(np, "msi-parent", 0)) { + dev_err(dev, "failed to find msi-parent\n"); + return -EINVAL; + } + + pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); + if (!pcie) + return -ENOMEM; + + mv_pci = devm_kzalloc(dev, sizeof(*mv_pci), GFP_KERNEL); + if (!mv_pci) + return -ENOMEM; + + mv_pci->pdev = pdev; + mv_pci->ops = &lx_pcie_pab_ops; + mv_pci->rp.ops = &lx_pcie_rp_ops; + pcie->pci = mv_pci; + + platform_set_drvdata(pdev, pcie); + + pcie->irq = platform_get_irq_byname(pdev, "intr"); + if (pcie->irq < 0) { + dev_err(&pdev->dev, "Can't get intr irq.\n"); + return pcie->irq; + } + ret = devm_request_irq(dev, pcie->irq, lx_pcie_handler, + IRQF_SHARED, pdev->name, pcie); + if (ret) { + dev_err(dev, "Can't register LX PCIe IRQ.\n"); + return ret; + } + + ret = mobiveil_pcie_host_probe(mv_pci); + if (ret) { + dev_err(dev, "pci-lx: fail to probe!\n"); + return ret; + } + + if (!lx_pcie_is_bridge(pcie)) + return -ENODEV; + + return 0; +} + +static struct platform_driver lx_pcie_driver = { + .driver = { + .name = "lx-pcie", + .of_match_table = lx_pcie_of_match, + .suppress_bind_attrs = true, + }, +}; + +builtin_platform_driver_probe(lx_pcie_driver, lx_pcie_probe); diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c index b1d67a697ecc..eade5a8002d1 100644 --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c @@ -249,8 +249,9 @@ int mobiveil_host_init(struct mobiveil_pcie *pcie, bool reinit) pab_ctrl |= (1 << AMBA_PIO_ENABLE_SHIFT) | (1 << PEX_PIO_ENABLE_SHIFT); csr_writel(pcie, pab_ctrl, PAB_CTRL); - csr_writel(pcie, (PAB_INTP_INTX_MASK | PAB_INTP_MSI_MASK), - PAB_INTP_AMBA_MISC_ENB); + value = PAB_INTP_INTX_MASK | PAB_INTP_MSI | PAB_INTP_RESET | + PAB_INTP_PCIE_UE | PAB_INTP_IE_PMREDI | PAB_INTP_IE_EC; + csr_writel(pcie, value, PAB_INTP_AMBA_MISC_ENB); /* * program PIO Enable Bit to 1 and Config Window Enable Bit to 1 in diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h index 51195db09347..ddd736fa2042 100644 --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h @@ -41,6 +41,8 @@ #define PAGE_LO_MASK 0x3ff #define PAGE_SEL_OFFSET_SHIFT 10 +#define PAB_ACTIVITY_STAT 0x81c + #define PAB_AXI_PIO_CTRL 0x0840 #define APIO_EN_MASK 0xf @@ -49,8 +51,17 @@ #define PAB_INTP_AMBA_MISC_ENB 0x0b0c #define PAB_INTP_AMBA_MISC_STAT 0x0b1c -#define PAB_INTP_INTX_MASK 0x01e0 -#define PAB_INTP_MSI_MASK 0x8 +#define PAB_INTP_RESET (0x1 << 1) +#define PAB_INTP_MSI (0x1 << 3) +#define PAB_INTP_INTA (0x1 << 5) +#define PAB_INTP_INTB (0x1 << 6) +#define PAB_INTP_INTC (0x1 << 7) +#define PAB_INTP_INTD (0x1 << 8) +#define PAB_INTP_PCIE_UE (0x1 << 9) +#define PAB_INTP_IE_PMREDI (0x1 << 29) +#define PAB_INTP_IE_EC (0x1 << 30) +#define PAB_INTP_INTX_MASK (PAB_INTP_INTA | PAB_INTP_INTB |\ + PAB_INTP_INTC | PAB_INTP_INTD) #define PAB_AXI_AMAP_CTRL(win) PAB_REG_ADDR(0x0ba0, win) #define WIN_ENABLE_SHIFT 0