From patchwork Tue May 22 09:06:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Douglas X-Patchwork-Id: 918088 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=cadence.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cadence.com header.i=@cadence.com header.b="Mb8H66g1"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40qqWs1CLLz9s5w for ; Tue, 22 May 2018 19:06:33 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751562AbeEVJG3 (ORCPT ); Tue, 22 May 2018 05:06:29 -0400 Received: from mail-by2nam01on0042.outbound.protection.outlook.com ([104.47.34.42]:36496 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751060AbeEVJG2 (ORCPT ); Tue, 22 May 2018 05:06:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cadence.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=PGXAAnKmV/2JwITjrrDbbpTF8upUr+O11l6D5sZuY9k=; b=Mb8H66g16CEP5H3+/81jRLlEAobFem5/fiJMRABoteZFySMVs22VYgY9fcAqVHiS3Y41uDrksRCsdAGi+6djfXdcORboVjp87QSucUqb747Al+92WA3Er5nrFQxvQYtV1k6ZOYryLfkoAZYBIfflVL56TqEMXxCgLZdCEWsGFbM= Received: from SN6PR07MB4512.namprd07.prod.outlook.com (52.135.94.11) by SN6PR07MB4863.namprd07.prod.outlook.com (52.135.75.11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.776.11; Tue, 22 May 2018 09:06:26 +0000 Received: from SN6PR07MB4512.namprd07.prod.outlook.com ([fe80::b8bd:affc:423a:3607]) by SN6PR07MB4512.namprd07.prod.outlook.com ([fe80::b8bd:affc:423a:3607%13]) with mapi id 15.20.0776.015; Tue, 22 May 2018 09:06:26 +0000 From: Alan Douglas To: "bhelgaas@google.com" , "kishon@ti.com" , "lorenzo.pieralisi@arm.com" , "linux-pci@vger.kernel.org" CC: "cyrille.pitchen@free-electrons.com" , "linux-pci@vger.kernel.org" , "devicetree@vger.kernel.org" , "nsekhar@ti.com" Subject: [PATCH v2 2/4] PCI: cadence: Add generic PHY support to host and EP drivers Thread-Topic: [PATCH v2 2/4] PCI: cadence: Add generic PHY support to host and EP drivers Thread-Index: AdPxq2t85WfGTmsRT/S4pkvItynrPw== Date: Tue, 22 May 2018 09:06:26 +0000 Message-ID: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-dg-ref: PG1ldGE+PGF0IG5tPSJib2R5LnR4dCIgcD0iYzpcdXNlcnNcYWRvdWdsYXNcYXBwZGF0YVxyb2FtaW5nXDA5ZDg0OWI2LTMyZDMtNGE0MC04NWVlLTZiODRiYTI5ZTM1Ylxtc2dzXG1zZy02YzEzYWE2MS01ZDlmLTExZTgtODZlNi1hNDRjYzhlYzVlY2RcYW1lLXRlc3RcNmMxM2FhNjItNWQ5Zi0xMWU4LTg2ZTYtYTQ0Y2M4ZWM1ZWNkYm9keS50eHQiIHN6PSI3NjA0IiB0PSIxMzE3MTQ1MzU5Mzk1MjM3NTUiIGg9IkR0azFqM2VVMUhnYlJxRGkwZURITGwyRmJXYz0iIGlkPSIiIGJsPSIwIiBibz0iMSIvPjwvbWV0YT4= authentication-results: spf=none (sender IP is ) smtp.mailfrom=adouglas@cadence.com; x-originating-ip: [185.217.253.59] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; SN6PR07MB4863; 7:Vc75LXLlkBG8izroZwpKCHasgeX/lV7jRNXT/B/x7hkrSIOEm7nxQlmBNHicLMUrh6UYHTCX52LGUQkEdm6a84SAfYq8HhFh0H7Ye/0WvgAHLExSudCL1gS6DE5oq/YfIurbX/Lv3Mbr78seM/V9gzrNEPb7sJgw/RUQvyluw4biH6scMAWDQe+2UhPbbx5qbrpLlmEJkljQaGQ/SAdRTNoygKDP1GIZ5jUeQP/XlrVgowiNG9sjzZ7+rXqj+SaJ; 20:9FELKIfMQGKovBepl2sGdBVxMDFBUNG0GDHq7P9HV66sY9KPEFp7oVwB1eWE3oWl7iJRrMPqJCUieUhT2cxKITBhscOBTh9nP/WuVIKw/JnIL653JZj12rcqugbJIesuRq7ojKDPphyqubmXOEzJTJ9eU3X2rtqmozZnwGGXGP/qXd/vkA3MHBcg/Kn+gb9AKSVdaz695t5L9yT0TPRtAWC6ZjbPo+h9nqokMFlFIsuzO4XiCTXwJRE9rhBNJTJg x-ms-exchange-antispam-srfa-diagnostics: SOS; x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:SN6PR07MB4863; x-ms-traffictypediagnostic: SN6PR07MB4863: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(72806322054110); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3231254)(944501410)(52105095)(93006095)(93001095)(10201501046)(3002001)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(6072148)(201708071742011)(7699016); SRVR:SN6PR07MB4863; BCL:0; PCL:0; RULEID:; SRVR:SN6PR07MB4863; x-forefront-prvs: 0680FADD48 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(366004)(346002)(376002)(39380400002)(39860400002)(396003)(189003)(36092001)(199004)(305945005)(68736007)(3846002)(6116002)(186003)(14454004)(33656002)(7696005)(59450400001)(55016002)(26005)(9686003)(99286004)(6506007)(102836004)(97736004)(53936002)(7736002)(25786009)(66066001)(486006)(74316002)(81166006)(54906003)(110136005)(478600001)(8676002)(8936002)(81156014)(3280700002)(2906002)(316002)(3660700001)(106356001)(105586002)(4326008)(2900100001)(2201001)(5660300001)(5250100002)(6436002)(2501003)(86362001)(476003)(41533002); DIR:OUT; SFP:1101; SCL:1; SRVR:SN6PR07MB4863; H:SN6PR07MB4512.namprd07.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: cadence.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: zm2QIWTaN6S81DaTiW1UeEFfzudV9nB0OFf57YiWG8UHa+HMKJvinruxpa5ytZqCkYacndY87xAlzNDoowYn3CmBa4hMQc7j9ucs+mm9WPj7Vhn2IYkBDVpHaC1RPqLTLET9yMNuAliJbzMqvsKjZzKIIovdy11+bJhmGC9B5odnYGXQtw7FWTOc35yfmVXi2cfAVCjkZId4N00bjhFf8A== spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 686851e0-3e6b-4d9a-abf7-08d5bfc34c96 X-OriginatorOrg: cadence.com X-MS-Exchange-CrossTenant-Network-Message-Id: 686851e0-3e6b-4d9a-abf7-08d5bfc34c96 X-MS-Exchange-CrossTenant-originalarrivaltime: 22 May 2018 09:06:26.6170 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: d36035c5-6ce6-4662-a3dc-e762e61ae4c9 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN6PR07MB4863 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Alan Douglas If PHYs are present, they will be initialized and enabled in driver probe, and disabled in driver shutdown. Signed-off-by: Alan Douglas --- drivers/pci/cadence/pcie-cadence-ep.c | 14 ++++- drivers/pci/cadence/pcie-cadence-host.c | 31 +++++++++++ drivers/pci/cadence/pcie-cadence.c | 93 +++++++++++++++++++++++++++++++++ drivers/pci/cadence/pcie-cadence.h | 7 +++ 4 files changed, 144 insertions(+), 1 deletion(-) diff --git a/drivers/pci/cadence/pcie-cadence-ep.c b/drivers/pci/cadence/pcie-cadence-ep.c index 3d8283e..2581caf 100644 --- a/drivers/pci/cadence/pcie-cadence-ep.c +++ b/drivers/pci/cadence/pcie-cadence-ep.c @@ -439,6 +439,7 @@ static int cdns_pcie_ep_probe(struct platform_device *pdev) struct pci_epc *epc; struct resource *res; int ret; + int phy_count; ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL); if (!ep) @@ -472,6 +473,12 @@ static int cdns_pcie_ep_probe(struct platform_device *pdev) if (!ep->ob_addr) return -ENOMEM; + ret = cdns_pcie_init_phy(dev, pcie); + if (ret) { + dev_err(dev, "failed to init phy\n"); + return ret; + } + platform_set_drvdata(pdev, pcie); pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (ret < 0) { @@ -520,6 +527,10 @@ static int cdns_pcie_ep_probe(struct platform_device *pdev) err_get_sync: pm_runtime_disable(dev); + cdns_pcie_disable_phy(pcie); + phy_count = pcie->phy_count; + while (phy_count--) + device_link_del(pcie->link[phy_count]); return ret; } @@ -527,6 +538,7 @@ static int cdns_pcie_ep_probe(struct platform_device *pdev) static void cdns_pcie_ep_shutdown(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct cdns_pcie *pcie = dev_get_drvdata(dev); int ret; ret = pm_runtime_put_sync(dev); @@ -535,7 +547,7 @@ static void cdns_pcie_ep_shutdown(struct platform_device *pdev) pm_runtime_disable(dev); - /* The PCIe controller can't be disabled. */ + cdns_pcie_disable_phy(pcie); } static struct platform_driver cdns_pcie_ep_driver = { diff --git a/drivers/pci/cadence/pcie-cadence-host.c b/drivers/pci/cadence/pcie-cadence-host.c index a4ebbd3..7536926a 100644 --- a/drivers/pci/cadence/pcie-cadence-host.c +++ b/drivers/pci/cadence/pcie-cadence-host.c @@ -58,6 +58,9 @@ static void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn, return pcie->reg_base + (where & 0xfff); } + /* Check that the link is up */ + if (!(cdns_pcie_readl(pcie, CDNS_PCIE_LM_BASE) & 0x1)) + return NULL; /* Update Output registers for AXI region 0. */ addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(12) | @@ -239,6 +242,7 @@ static int cdns_pcie_host_probe(struct platform_device *pdev) struct cdns_pcie *pcie; struct resource *res; int ret; + int phy_count; bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc)); if (!bridge) @@ -290,6 +294,13 @@ static int cdns_pcie_host_probe(struct platform_device *pdev) } pcie->mem_res = res; + ret = cdns_pcie_init_phy(dev, pcie); + if (ret) { + dev_err(dev, "failed to init phy\n"); + return ret; + } + platform_set_drvdata(pdev, pcie); + pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (ret < 0) { @@ -322,15 +333,35 @@ static int cdns_pcie_host_probe(struct platform_device *pdev) err_get_sync: pm_runtime_disable(dev); + cdns_pcie_disable_phy(pcie); + phy_count = pcie->phy_count; + while (phy_count--) + device_link_del(pcie->link[phy_count]); return ret; } +static void cdns_pcie_shutdown(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct cdns_pcie *pcie = dev_get_drvdata(dev); + int ret; + + ret = pm_runtime_put_sync(dev); + if (ret < 0) + dev_dbg(dev, "pm_runtime_put_sync failed\n"); + + pm_runtime_disable(dev); + cdns_pcie_disable_phy(pcie); +} + + static struct platform_driver cdns_pcie_host_driver = { .driver = { .name = "cdns-pcie-host", .of_match_table = cdns_pcie_host_of_match, }, .probe = cdns_pcie_host_probe, + .shutdown = cdns_pcie_shutdown, }; builtin_platform_driver(cdns_pcie_host_driver); diff --git a/drivers/pci/cadence/pcie-cadence.c b/drivers/pci/cadence/pcie-cadence.c index 138d113..681609a 100644 --- a/drivers/pci/cadence/pcie-cadence.c +++ b/drivers/pci/cadence/pcie-cadence.c @@ -124,3 +124,96 @@ void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r) cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), 0); cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), 0); } + +void cdns_pcie_disable_phy(struct cdns_pcie *pcie) +{ + int i = pcie->phy_count; + + while (i--) { + phy_power_off(pcie->phy[i]); + phy_exit(pcie->phy[i]); + } +} + +int cdns_pcie_enable_phy(struct cdns_pcie *pcie) +{ + int ret; + int i; + + for (i = 0; i < pcie->phy_count; i++) { + ret = phy_init(pcie->phy[i]); + if (ret < 0) + goto err_phy; + + ret = phy_power_on(pcie->phy[i]); + if (ret < 0) { + phy_exit(pcie->phy[i]); + goto err_phy; + } + } + + return 0; + +err_phy: + while (--i >= 0) { + phy_power_off(pcie->phy[i]); + phy_exit(pcie->phy[i]); + } + + return ret; +} + +int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie) +{ + struct device_node *np = dev->of_node; + int phy_count; + struct phy **phy; + struct device_link **link; + int i; + int ret; + const char *name; + + phy_count = of_property_count_strings(np, "phy-names"); + if (phy_count < 1) { + dev_err(dev, "no phy-names. PHY will not be initialized\n"); + pcie->phy_count = 0; + return 0; + } + + phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL); + if (!phy) + return -ENOMEM; + + link = devm_kzalloc(dev, sizeof(*link) * phy_count, GFP_KERNEL); + if (!link) + return -ENOMEM; + + for (i = 0; i < phy_count; i++) { + of_property_read_string_index(np, "phy-names", i, &name); + phy[i] = devm_phy_get(dev, name); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + link[i] = device_link_add(dev, &phy[i]->dev, DL_FLAG_STATELESS); + if (!link[i]) { + ret = -EINVAL; + goto err_link; + } + } + + pcie->phy_count = phy_count; + pcie->phy = phy; + pcie->link = link; + + ret = cdns_pcie_enable_phy(pcie); + if (ret) + goto err_link; + + return 0; + +err_link: + while (--i >= 0) + device_link_del(link[i]); + + return ret; +} diff --git a/drivers/pci/cadence/pcie-cadence.h b/drivers/pci/cadence/pcie-cadence.h index ed336cc..b342c80 100644 --- a/drivers/pci/cadence/pcie-cadence.h +++ b/drivers/pci/cadence/pcie-cadence.h @@ -8,6 +8,7 @@ #include #include +#include /* * Local Management Registers @@ -229,6 +230,9 @@ struct cdns_pcie { struct resource *mem_res; bool is_rc; u8 bus; + int phy_count; + struct phy **phy; + struct device_link **link; }; /* Register access */ @@ -307,5 +311,8 @@ void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn, u32 r, u64 cpu_addr); void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r); +void cdns_pcie_disable_phy(struct cdns_pcie *pcie); +int cdns_pcie_enable_phy(struct cdns_pcie *pcie); +int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie); #endif /* _PCIE_CADENCE_H */