From patchwork Wed Sep 8 06:59:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Zhu X-Patchwork-Id: 12480445 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EEFA7C433F5 for ; Wed, 8 Sep 2021 07:22:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CB07A61168 for ; Wed, 8 Sep 2021 07:22:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345425AbhIHHX3 (ORCPT ); Wed, 8 Sep 2021 03:23:29 -0400 Received: from inva020.nxp.com ([92.121.34.13]:47664 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229811AbhIHHX2 (ORCPT ); Wed, 8 Sep 2021 03:23:28 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 065851A2E57; Wed, 8 Sep 2021 09:22:20 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 8FE8B1A2E30; Wed, 8 Sep 2021 09:22:19 +0200 (CEST) Received: from localhost.localdomain (shlinux2.ap.freescale.net [10.192.224.44]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 3A71A183AC88; Wed, 8 Sep 2021 15:22:18 +0800 (+08) From: Richard Zhu To: l.stach@pengutronix.de, bhelgaas@google.com, lorenzo.pieralisi@arm.com Cc: linux-pci@vger.kernel.org, linux-imx@nxp.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Richard Zhu Subject: [PATCH 1/3] PCI: imx: encapsulate the clock enable into one standalone function Date: Wed, 8 Sep 2021 14:59:24 +0800 Message-Id: <1631084366-24785-1-git-send-email-hongxing.zhu@nxp.com> X-Mailer: git-send-email 2.7.4 X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org No function changes, just encapsulate the i.MX PCIe clocks enable operations into one standalone function Signed-off-by: Richard Zhu Reported-by: kernel test robot --- drivers/pci/controller/dwc/pci-imx6.c | 82 +++++++++++++++++---------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 80fc98acf097..0264432e4c4a 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -143,6 +143,8 @@ struct imx6_pcie { #define PHY_RX_OVRD_IN_LO_RX_DATA_EN BIT(5) #define PHY_RX_OVRD_IN_LO_RX_PLL_EN BIT(3) +static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie); + static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, bool exp_val) { struct dw_pcie *pci = imx6_pcie->pci; @@ -498,33 +500,12 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) } } - ret = clk_prepare_enable(imx6_pcie->pcie_phy); - if (ret) { - dev_err(dev, "unable to enable pcie_phy clock\n"); - goto err_pcie_phy; - } - - ret = clk_prepare_enable(imx6_pcie->pcie_bus); + ret = imx6_pcie_clk_enable(imx6_pcie); if (ret) { - dev_err(dev, "unable to enable pcie_bus clock\n"); - goto err_pcie_bus; + dev_err(dev, "unable to enable pcie clocks\n"); + goto err_clks; } - ret = clk_prepare_enable(imx6_pcie->pcie); - if (ret) { - dev_err(dev, "unable to enable pcie clock\n"); - goto err_pcie; - } - - ret = imx6_pcie_enable_ref_clk(imx6_pcie); - if (ret) { - dev_err(dev, "unable to enable pcie ref clock\n"); - goto err_ref_clk; - } - - /* allow the clocks to stabilize */ - usleep_range(200, 500); - /* Some boards don't have PCIe reset GPIO. */ if (gpio_is_valid(imx6_pcie->reset_gpio)) { gpio_set_value_cansleep(imx6_pcie->reset_gpio, @@ -578,13 +559,7 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) return; -err_ref_clk: - clk_disable_unprepare(imx6_pcie->pcie); -err_pcie: - clk_disable_unprepare(imx6_pcie->pcie_bus); -err_pcie_bus: - clk_disable_unprepare(imx6_pcie->pcie_phy); -err_pcie_phy: +err_clks: if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) { ret = regulator_disable(imx6_pcie->vpcie); if (ret) @@ -914,6 +889,51 @@ static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie) usleep_range(1000, 10000); } +static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie) +{ + struct dw_pcie *pci = imx6_pcie->pci; + struct device *dev = pci->dev; + int ret; + + ret = clk_prepare_enable(imx6_pcie->pcie_phy); + if (ret) { + dev_err(dev, "unable to enable pcie_phy clock\n"); + return ret; + } + + ret = clk_prepare_enable(imx6_pcie->pcie_bus); + if (ret) { + dev_err(dev, "unable to enable pcie_bus clock\n"); + goto err_pcie_bus; + } + + ret = clk_prepare_enable(imx6_pcie->pcie); + if (ret) { + dev_err(dev, "unable to enable pcie clock\n"); + goto err_pcie; + } + + ret = imx6_pcie_enable_ref_clk(imx6_pcie); + if (ret) { + dev_err(dev, "unable to enable pcie ref clock\n"); + goto err_ref_clk; + } + + /* allow the clocks to stabilize */ + usleep_range(200, 500); + return 0; + +err_ref_clk: + clk_disable_unprepare(imx6_pcie->pcie); +err_pcie: + clk_disable_unprepare(imx6_pcie->pcie_bus); +err_pcie_bus: + clk_disable_unprepare(imx6_pcie->pcie_phy); + + return ret; + +} + static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie) { clk_disable_unprepare(imx6_pcie->pcie); From patchwork Wed Sep 8 06:59:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Zhu X-Patchwork-Id: 12480449 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3ADBAC433F5 for ; Wed, 8 Sep 2021 07:22:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1D9C761155 for ; Wed, 8 Sep 2021 07:22:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347857AbhIHHXa (ORCPT ); Wed, 8 Sep 2021 03:23:30 -0400 Received: from inva021.nxp.com ([92.121.34.21]:45780 "EHLO inva021.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239498AbhIHHX3 (ORCPT ); Wed, 8 Sep 2021 03:23:29 -0400 Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id D431E204514; Wed, 8 Sep 2021 09:22:20 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 71EBB202EEF; Wed, 8 Sep 2021 09:22:20 +0200 (CEST) Received: from localhost.localdomain (shlinux2.ap.freescale.net [10.192.224.44]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 1A67B183AD2A; Wed, 8 Sep 2021 15:22:19 +0800 (+08) From: Richard Zhu To: l.stach@pengutronix.de, bhelgaas@google.com, lorenzo.pieralisi@arm.com Cc: linux-pci@vger.kernel.org, linux-imx@nxp.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Richard Zhu Subject: [PATCH 2/3] PCI: imx: add err check to host init and fix regulator dump Date: Wed, 8 Sep 2021 14:59:25 +0800 Message-Id: <1631084366-24785-2-git-send-email-hongxing.zhu@nxp.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1631084366-24785-1-git-send-email-hongxing.zhu@nxp.com> References: <1631084366-24785-1-git-send-email-hongxing.zhu@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Since there is error return check of the host_init callback, add error check to imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) function. Because that i.MX PCIe doesn't support the hot-plug feature. To save power consumption as much as possible, turn off the clocks and power supplies when the PCIe PHY link is never came up in probe procedure. When PCIe link is never came up and vpcie regulator is present, there would be following dump when try to put the regulator. Disable this regulator to fix this dump when link is never came up. [ 2.335880] imx6q-pcie 33800000.pcie: Phy link never came up [ 2.341642] imx6q-pcie: probe of 33800000.pcie failed with error -110 [ 2.348160] ------------[ cut here ]------------ [ 2.352778] WARNING: CPU: 3 PID: 119 at drivers/regulator/core.c:2256 _regulator_put.part.0+0x14c/0x158 [ 2.362184] Modules linked in: [ 2.365243] CPU: 3 PID: 119 Comm: kworker/u8:2 Not tainted 5.13.0-rc7-next-20210625-94710-ge4e92b2588a3 #10 [ 2.374987] Hardware name: FSL i.MX8MM EVK board (DT) [ 2.380040] Workqueue: events_unbound async_run_entry_fn [ 2.385359] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--) [ 2.391369] pc : _regulator_put.part.0+0x14c/0x158 [ 2.396163] lr : regulator_put+0x34/0x48 [ 2.400088] sp : ffff8000122ebb30 [ 2.403400] x29: ffff8000122ebb30 x28: ffff800011be7000 x27: 0000000000000000 [ 2.410546] x26: 0000000000000000 x25: 0000000000000000 x24: ffff00000025f2bc [ 2.417689] x23: ffff00000025f2c0 x22: ffff00000025f010 x21: ffff8000122ebc18 [ 2.424834] x20: ffff800011e3fa60 x19: ffff00000375fd80 x18: 0000000000000010 [ 2.431979] x17: 000000040044ffff x16: 00400032b5503510 x15: 0000000000000108 [ 2.439124] x14: ffff0000003cc938 x13: 00000000ffffffea x12: 0000000000000000 [ 2.446267] x11: 0000000000000000 x10: ffff80001076ba88 x9 : ffff80001076a540 [ 2.453411] x8 : ffff00000025f2c0 x7 : ffff0000001f4450 x6 : ffff000000176cd8 [ 2.460556] x5 : ffff000003857880 x4 : 0000000000000000 x3 : ffff800011e3fe30 [ 2.467700] x2 : ffff0000003cc4c0 x1 : 0000000000000000 x0 : 0000000000000001 [ 2.474847] Call trace: [ 2.477295] _regulator_put.part.0+0x14c/0x158 [ 2.481742] regulator_put+0x34/0x48 [ 2.485322] devm_regulator_release+0x10/0x18 [ 2.489681] release_nodes+0x38/0x60 [ 2.493262] devres_release_all+0x88/0xd0 [ 2.497276] really_probe+0xd0/0x2e8 [ 2.500858] __driver_probe_device+0x74/0xd8 [ 2.505137] driver_probe_device+0x7c/0x108 [ 2.509325] __device_attach_driver+0x8c/0xd0 [ 2.513685] bus_for_each_drv+0x74/0xc0 [ 2.517531] __device_attach_async_helper+0xb4/0xd8 [ 2.522419] async_run_entry_fn+0x30/0x100 [ 2.526521] process_one_work+0x19c/0x320 [ 2.530532] worker_thread+0x48/0x418 [ 2.534199] kthread+0x14c/0x158 [ 2.537432] ret_from_fork+0x10/0x18 [ 2.541013] ---[ end trace 3664ca4a50ce849b ]--- Signed-off-by: Richard Zhu --- drivers/pci/controller/dwc/pci-imx6.c | 28 +++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 0264432e4c4a..129928e42f84 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -144,6 +144,7 @@ struct imx6_pcie { #define PHY_RX_OVRD_IN_LO_RX_PLL_EN BIT(3) static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie); +static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie); static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, bool exp_val) { @@ -485,24 +486,24 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie) dev_err(dev, "PCIe PLL lock timeout\n"); } -static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) +static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) { struct dw_pcie *pci = imx6_pcie->pci; struct device *dev = pci->dev; - int ret; + int ret, err; if (imx6_pcie->vpcie && !regulator_is_enabled(imx6_pcie->vpcie)) { ret = regulator_enable(imx6_pcie->vpcie); if (ret) { dev_err(dev, "failed to enable vpcie regulator: %d\n", ret); - return; + return ret; } } - ret = imx6_pcie_clk_enable(imx6_pcie); - if (ret) { - dev_err(dev, "unable to enable pcie clocks\n"); + err = imx6_pcie_clk_enable(imx6_pcie); + if (err) { + dev_err(dev, "unable to enable pcie clocks: %d\n", err); goto err_clks; } @@ -557,7 +558,7 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) break; } - return; + return 0; err_clks: if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) { @@ -566,6 +567,7 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) dev_err(dev, "failed to disable vpcie regulator: %d\n", ret); } + return err; } static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie) @@ -810,17 +812,27 @@ static int imx6_pcie_start_link(struct dw_pcie *pci) dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0), dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG1)); imx6_pcie_reset_phy(imx6_pcie); + imx6_pcie_clk_disable(imx6_pcie); + if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) + regulator_disable(imx6_pcie->vpcie); return ret; } static int imx6_pcie_host_init(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct device *dev = pci->dev; struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci); + int ret; imx6_pcie_assert_core_reset(imx6_pcie); imx6_pcie_init_phy(imx6_pcie); - imx6_pcie_deassert_core_reset(imx6_pcie); + ret = imx6_pcie_deassert_core_reset(imx6_pcie); + if (ret < 0) { + dev_err(dev, "pcie host init failed: %d.\n", ret); + return ret; + } + imx6_setup_phy_mpll(imx6_pcie); return 0; From patchwork Wed Sep 8 06:59:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Zhu X-Patchwork-Id: 12480447 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E610C433EF for ; Wed, 8 Sep 2021 07:22:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7FAE161102 for ; Wed, 8 Sep 2021 07:22:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347872AbhIHHXb (ORCPT ); Wed, 8 Sep 2021 03:23:31 -0400 Received: from inva020.nxp.com ([92.121.34.13]:47828 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235185AbhIHHX3 (ORCPT ); Wed, 8 Sep 2021 03:23:29 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 53DFF1A2E4A; Wed, 8 Sep 2021 09:22:21 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id EE7EC1A4595; Wed, 8 Sep 2021 09:22:20 +0200 (CEST) Received: from localhost.localdomain (shlinux2.ap.freescale.net [10.192.224.44]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id EFB8C183AD45; Wed, 8 Sep 2021 15:22:19 +0800 (+08) From: Richard Zhu To: l.stach@pengutronix.de, bhelgaas@google.com, lorenzo.pieralisi@arm.com Cc: linux-pci@vger.kernel.org, linux-imx@nxp.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@pengutronix.de, Richard Zhu Subject: [PATCH 3/3] PCI: imx: add compliance tests mode to enable measure signal quality Date: Wed, 8 Sep 2021 14:59:26 +0800 Message-Id: <1631084366-24785-3-git-send-email-hongxing.zhu@nxp.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1631084366-24785-1-git-send-email-hongxing.zhu@nxp.com> References: <1631084366-24785-1-git-send-email-hongxing.zhu@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Refer to the system board signal Quality of PCIe archiecture PHY test specification. Signal quality tests can be executed with devices in the polling.compliance state. To let the device support polling.compliance stat, the clocks and powers shouldn't be turned off during the compliance tests although the PHY link might be down. Add the i.MX PCIe compliance tests mode enable option to keep the and powers on, and finish the driver probe without error return. Use the "pcie_cmp_enabled=yes" in kernel command line to enable the compliance tests mode. Signed-off-by: Richard Zhu --- drivers/pci/controller/dwc/pci-imx6.c | 41 +++++++++++++++++++++------ 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 129928e42f84..3aef0e86f1c2 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -143,6 +143,7 @@ struct imx6_pcie { #define PHY_RX_OVRD_IN_LO_RX_DATA_EN BIT(5) #define PHY_RX_OVRD_IN_LO_RX_PLL_EN BIT(3) +static int imx6_pcie_cmp_enabled; static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie); static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie); @@ -748,10 +749,12 @@ static int imx6_pcie_start_link(struct dw_pcie *pci) * started in Gen2 mode, there is a possibility the devices on the * bus will not be detected at all. This happens with PCIe switches. */ - tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP); - tmp &= ~PCI_EXP_LNKCAP_SLS; - tmp |= PCI_EXP_LNKCAP_SLS_2_5GB; - dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, tmp); + if (!imx6_pcie_cmp_enabled) { + tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP); + tmp &= ~PCI_EXP_LNKCAP_SLS; + tmp |= PCI_EXP_LNKCAP_SLS_2_5GB; + dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, tmp); + } /* Start LTSSM. */ imx6_pcie_ltssm_enable(dev); @@ -812,9 +815,12 @@ static int imx6_pcie_start_link(struct dw_pcie *pci) dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0), dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG1)); imx6_pcie_reset_phy(imx6_pcie); - imx6_pcie_clk_disable(imx6_pcie); - if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) - regulator_disable(imx6_pcie->vpcie); + if (!imx6_pcie_cmp_enabled) { + imx6_pcie_clk_disable(imx6_pcie); + if (imx6_pcie->vpcie + && regulator_is_enabled(imx6_pcie->vpcie) > 0) + regulator_disable(imx6_pcie->vpcie); + } return ret; } @@ -1010,6 +1016,17 @@ static const struct dev_pm_ops imx6_pcie_pm_ops = { imx6_pcie_resume_noirq) }; +static int __init imx6_pcie_compliance_test_enable(char *str) +{ + if (!strcmp(str, "yes")) { + pr_info("Enable the i.MX PCIe TX/CLK compliance tests mode.\n"); + imx6_pcie_cmp_enabled = 1; + } + return 1; +} + +__setup("pcie_cmp_enabled=", imx6_pcie_compliance_test_enable); + static int imx6_pcie_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1187,8 +1204,16 @@ static int imx6_pcie_probe(struct platform_device *pdev) return ret; ret = dw_pcie_host_init(&pci->pp); - if (ret < 0) + if (ret < 0) { + if (imx6_pcie_cmp_enabled) { + /* The PCIE clocks and powers wouldn't be turned off */ + dev_info(dev, "To do the compliance tests.\n"); + ret = 0; + } else { + dev_err(dev, "Unable to add pcie port.\n"); + } return ret; + } if (pci_msi_enabled()) { u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI);