From mboxrd@z Thu Jan 1 00:00:00 1970 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 403A8C433EF for ; Thu, 25 Nov 2021 00:30:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353794AbhKYAeI (ORCPT ); Wed, 24 Nov 2021 19:34:08 -0500 Received: from mail.kernel.org ([198.145.29.99]:46828 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346197AbhKYAbb (ORCPT ); Wed, 24 Nov 2021 19:31:31 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id AAFCB610D0; Thu, 25 Nov 2021 00:26:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1637799990; bh=+16WFsjZ/j7fbSktNs2odenX84sLcBGSdh8N5OYfZLc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JXhLdsXi0L0do8mm04XIRTGPxD9hlvu+XoCnMw1GfXKki+OYpEh6ivoj7SWm4YWPG J6xkF16CsdC2IwpX5Jp30XTAgsGb2qnsO8gjIu+eRV8Dixnpfmn3aAFVcqntnDg7t/ izWVIYezkLVsX2jGhIrFbN1JrEMa0cKaz8mX+rf3WCagk4My7a+DG0FC0gRbG5k4ip tCagTGekXu2Q96BzvySMMUDaJETRCl215rfsi70qQWINzJMO7ChXNsMzld8tBFDZCN mH1AxNO1daMTv6Gnbth4mLa5A1b6nWKImgRhqJy5cGI4jJEpO1Wi51RxoETshteE2J 9OEY3g8BOGCuw== From: =?UTF-8?q?Marek=20Beh=C3=BAn?= To: Greg Kroah-Hartman , Sasha Levin Cc: pali@kernel.org, stable@vger.kernel.org, Tomasz Maciej Nowak , Lorenzo Pieralisi , Thomas Petazzoni , =?UTF-8?q?Marek=20Beh=C3=BAn?= Subject: [PATCH 5.4 05/22] PCI: aardvark: Issue PERST via GPIO Date: Thu, 25 Nov 2021 01:25:59 +0100 Message-Id: <20211125002616.31363-6-kabel@kernel.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211125002616.31363-1-kabel@kernel.org> References: <20211125002616.31363-1-kabel@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Pali Rohár commit 5169a9851daaa2782a7bd2bb83d5b1bd224b2879 upstream. Add support for issuing PERST via GPIO specified in 'reset-gpios' property (as described in PCI device tree bindings). Some buggy cards (e.g. Compex WLE900VX or WLE1216) are not detected after reboot when PERST is not issued during driver initialization. If bootloader already enabled link training then issuing PERST has no effect for some buggy cards (e.g. Compex WLE900VX) and these cards are not detected. We therefore clear the LINK_TRAINING_EN register before. It was observed that Compex WLE900VX card needs to be in PERST reset for at least 10ms if bootloader enabled link training. Tested on Turris MOX. Link: https://lore.kernel.org/r/20200430080625.26070-6-pali@kernel.org Tested-by: Tomasz Maciej Nowak Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi Acked-by: Thomas Petazzoni Signed-off-by: Marek Behún --- drivers/pci/controller/pci-aardvark.c | 43 ++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 813696986090..f65bb9b26ac3 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include #include +#include #include #include "../pci.h" @@ -252,6 +254,7 @@ struct advk_pcie { int root_bus_nr; int link_gen; struct pci_bridge_emul bridge; + struct gpio_desc *reset_gpio; }; static inline void advk_writel(struct advk_pcie *pcie, u32 val, u64 reg) @@ -414,10 +417,31 @@ static void advk_pcie_train_link(struct advk_pcie *pcie) 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; + advk_pcie_issue_perst(pcie); + /* Set to Direct mode */ reg = advk_readl(pcie, CTRL_CONFIG_REG); reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT); @@ -500,7 +524,8 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie) /* * PERST# signal could have been asserted by pinctrl subsystem before - * probe() callback has been called, making the endpoint going into + * 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. */ @@ -1344,6 +1369,22 @@ static int advk_pcie_probe(struct platform_device *pdev) return ret; } + pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node, + "reset-gpios", 0, + GPIOD_OUT_LOW, + "pcie1-reset"); + ret = PTR_ERR_OR_ZERO(pcie->reset_gpio); + if (ret) { + if (ret == -ENOENT) { + pcie->reset_gpio = NULL; + } else { + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get reset-gpio: %i\n", + ret); + return ret; + } + } + ret = of_pci_get_max_link_speed(dev->of_node); if (ret <= 0 || ret > 3) pcie->link_gen = 3; -- 2.32.0