From patchwork Mon Dec 6 14:55:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 521471 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 61AA1C41535 for ; Mon, 6 Dec 2021 15:15:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359365AbhLFPRJ (ORCPT ); Mon, 6 Dec 2021 10:17:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347392AbhLFPOp (ORCPT ); Mon, 6 Dec 2021 10:14:45 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1AA9DC0698D0; Mon, 6 Dec 2021 07:07:13 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id D9C78B8101B; Mon, 6 Dec 2021 15:07:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 28842C341C6; Mon, 6 Dec 2021 15:07:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1638803230; bh=ieIlto1nLiEmycXM0n/3xArPY8pynMRSG1MSUFgl6gM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1XLc5FlRdO03+ubTvROThSHsq9SjRSAtj+XHSaKCdp6Jn/7YH6AZFeLna04agKRbW e+CZI9n71tj9S4+L3UrIYmy/1F6wOcSnAFoevM9gmD3xjc8defOnr6qshFl2sDoFrT vOnq8mOyDpNumLd5h5rVfEghXdMfGJkuH5ZWQBaQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, =?utf-8?q?Marek_Beh=C3=BAn?= , =?utf-8?q?Pali_Roh=C3=A1?= =?utf-8?q?r?= , Lorenzo Pieralisi , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH 4.14 043/106] PCI: aardvark: Move PCIe reset card code to advk_pcie_train_link() Date: Mon, 6 Dec 2021 15:55:51 +0100 Message-Id: <20211206145556.881559749@linuxfoundation.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211206145555.386095297@linuxfoundation.org> References: <20211206145555.386095297@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Pali Rohár commit d0c6a3475b033960e85ae2bf176b14cab0a627d2 upstream. Move code which belongs to link training (delays and resets) into advk_pcie_train_link() function, so everything related to link training, including timings is at one place. After experiments it can be observed that link training in aardvark hardware is very sensitive to timings and delays, so it is a good idea to have this code at the same place as link training calls. This patch does not change behavior of aardvark initialization. Link: https://lore.kernel.org/r/20200907111038.5811-6-pali@kernel.org Tested-by: Marek Behún Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi Signed-off-by: Marek Behún Signed-off-by: Greg Kroah-Hartman --- drivers/pci/host/pci-aardvark.c | 64 +++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 30 deletions(-) --- a/drivers/pci/host/pci-aardvark.c +++ b/drivers/pci/host/pci-aardvark.c @@ -268,6 +268,25 @@ static void advk_pcie_set_ob_win(struct advk_writel(pcie, match_ls | BIT(0), OB_WIN_MATCH_LS(win_num)); } +static void advk_pcie_issue_perst(struct advk_pcie *pcie) +{ + u32 reg; + + if (!pcie->reset_gpio) + return; + + /* PERST does not work for some cards when link training is enabled */ + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); + reg &= ~LINK_TRAINING_EN; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + + /* 10ms delay is needed for some cards */ + dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); + gpiod_set_value_cansleep(pcie->reset_gpio, 1); + usleep_range(10000, 11000); + gpiod_set_value_cansleep(pcie->reset_gpio, 0); +} + static int advk_pcie_train_at_gen(struct advk_pcie *pcie, int gen) { int ret, neg_gen; @@ -316,6 +335,21 @@ static void advk_pcie_train_link(struct int neg_gen = -1, gen; /* + * Reset PCIe card via PERST# signal. Some cards are not detected + * during link training when they are in some non-initial state. + */ + advk_pcie_issue_perst(pcie); + + /* + * PERST# signal could have been asserted by pinctrl subsystem before + * probe() callback has been called or issued explicitly by reset gpio + * function advk_pcie_issue_perst(), making the endpoint going into + * fundamental reset. As required by PCI Express spec a delay for at + * least 100ms after such a reset before link training is needed. + */ + msleep(PCI_PM_D3COLD_WAIT); + + /* * Try link training at link gen specified by device tree property * 'max-link-speed'. If this fails, iteratively train at lower gen. */ @@ -347,25 +381,6 @@ err: dev_err(dev, "link never came up\n"); } -static void advk_pcie_issue_perst(struct advk_pcie *pcie) -{ - u32 reg; - - if (!pcie->reset_gpio) - return; - - /* PERST does not work for some cards when link training is enabled */ - reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); - reg &= ~LINK_TRAINING_EN; - advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); - - /* 10ms delay is needed for some cards */ - dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); - gpiod_set_value_cansleep(pcie->reset_gpio, 1); - usleep_range(10000, 11000); - gpiod_set_value_cansleep(pcie->reset_gpio, 0); -} - static void advk_pcie_setup_hw(struct advk_pcie *pcie) { u32 reg; @@ -375,8 +390,6 @@ static void advk_pcie_setup_hw(struct ad for (i = 0; i < 8; i++) advk_pcie_set_ob_win(pcie, i, 0, 0, 0, 0, 0, 0, 0); - advk_pcie_issue_perst(pcie); - /* Set to Direct mode */ reg = advk_readl(pcie, CTRL_CONFIG_REG); reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT); @@ -448,15 +461,6 @@ static void advk_pcie_setup_hw(struct ad reg |= PIO_CTRL_ADDR_WIN_DISABLE; advk_writel(pcie, reg, PIO_CTRL); - /* - * PERST# signal could have been asserted by pinctrl subsystem before - * probe() callback has been called or issued explicitly by reset gpio - * function advk_pcie_issue_perst(), making the endpoint going into - * fundamental reset. As required by PCI Express spec a delay for at - * least 100ms after such a reset before link training is needed. - */ - msleep(PCI_PM_D3COLD_WAIT); - advk_pcie_train_link(pcie); reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);