From patchwork Wed Apr 13 15:51:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Smirnov X-Patchwork-Id: 8824001 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4BA469F39A for ; Wed, 13 Apr 2016 15:51:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A31372025B for ; Wed, 13 Apr 2016 15:51:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7A764200E3 for ; Wed, 13 Apr 2016 15:51:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752901AbcDMPvy (ORCPT ); Wed, 13 Apr 2016 11:51:54 -0400 Received: from mail-pa0-f41.google.com ([209.85.220.41]:34884 "EHLO mail-pa0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752895AbcDMPvx (ORCPT ); Wed, 13 Apr 2016 11:51:53 -0400 Received: by mail-pa0-f41.google.com with SMTP id fs9so16783007pac.2; Wed, 13 Apr 2016 08:51:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=sNbzl9P9Egdn+MKt1sbF0aRFb4A2ZBORYvEfLE3Xfy8=; b=DYTSJToUGSD97zaV5APkjpkNGd0yslHqzHtyDayh1eQ2XvShr7jYchy8jFTMCdS2NS HyL1J2MLhN746rD0fj+OymlKgrXiQ1Nqzim4M3sOS1ZjscYeWgoPm9gxzZgK0aH+FXzZ l1mydredlPGhjzUfPKH1jMRV+COWv3OhY2Zo3Z32Dg/EOVXwETKIokLLFmXBWtyJR9SW xvjxj5W9Zz6A07OrCx0AA8bo7MeCnHwDDaJrLNFLezd5PlTwgECmLsV5zuS3whGmg4Az zCIP+42c6LnMNpoFGUTyBCpTz1Bs07H8y9ZRiL+89sccjQx2abDI+T+/B8HTE1PW8FrW iocw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=sNbzl9P9Egdn+MKt1sbF0aRFb4A2ZBORYvEfLE3Xfy8=; b=j0bB30Ona4wNjkoSpU6YX8gVJu/KJ3GuePhnIHTmGoY63QDhvC0RxYY45+lKFr0mZV LQOGIn3Dj9RJggfqzSKucEm9yKpkT9MI3TuowUS9cPgcExvS7GmH/H9K8hUmPCO+ddSg HXmfGJG+Rxpcx74s4ZM7wFAzzfaWCQugY3YEJfTGp8jLxWFLP0KIrfWIUsDwsCs+SzD+ f8jl3tEPR1wqClrn9eLH2Xj2yBm/rXqM7LZhOjOMErQoQGco2V9kiSRPIo4Nrk2LyEPM 5513Ip2qLYMdkf/iAgmTG/hbw9vN2kgGwTeS3CMOSdobs7ln1itCC7Y1ZekpHWLCmKKY 5nzw== X-Gm-Message-State: AOPr4FV8RhTB/H/Zhyc7eROFiqsRd7JknB9r7UhptVCxt5DfeJkny3AagH/5puur7/GRRg== X-Received: by 10.66.90.7 with SMTP id bs7mr13996357pab.118.1460562712274; Wed, 13 Apr 2016 08:51:52 -0700 (PDT) Received: from squirtle.localdomain.localdomain ([172.56.42.149]) by smtp.gmail.com with ESMTPSA id 129sm4735605pfx.68.2016.04.13.08.51.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 13 Apr 2016 08:51:51 -0700 (PDT) From: Andrey Smirnov X-Google-Original-From: Andrey Smirnov To: linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Andrey Smirnov , linux-kernel@vger.kernel.org, Bjorn Helgaas , Shawn Guo , Sascha Hauer , Richard Zhu , Lucas Stach , gary.bisson@boundarydevices.com Subject: [PATCH] PCI: imx6: Implement reset sequence for i.MX6+ Date: Wed, 13 Apr 2016 08:51:25 -0700 Message-Id: <1460562685-15168-1-git-send-email-asmirnov@spaceflightindustries.com> X-Mailer: git-send-email 2.5.5 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP I.MX6+ has a dedicated bit for reseting PCIe core, which should be used instead of a regular reset sequence since using the latter will hang the SoC. This commit is based on c34068d48273e24d392d9a49a38be807954420ed from http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git Signed-off-by: Andrey Smirnov --- arch/arm/boot/dts/imx6qp.dtsi | 3 ++ drivers/pci/host/pci-imx6.c | 82 +++++++++++++++++++---------- include/linux/mfd/syscon/imx6q-iomuxc-gpr.h | 1 + 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi index 1ada714..886dbf2 100644 --- a/arch/arm/boot/dts/imx6qp.dtsi +++ b/arch/arm/boot/dts/imx6qp.dtsi @@ -82,5 +82,8 @@ "ldb_di0", "ldb_di1", "prg"; }; + pcie: pcie@0x01000000 { + compatible = "fsl,imx6qp-pcie", "snps,dw-pcie"; + }; }; }; diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index eb5a275..99f5cac 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -85,6 +85,14 @@ struct imx6_pcie { #define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5) #define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3) +static inline bool is_imx6qp_pcie(struct imx6_pcie *imx6_pcie) +{ + struct pcie_port *pp = &imx6_pcie->pp; + struct device_node *np = pp->dev->of_node; + + return of_device_is_compatible(np, "fsl,imx6qp-pcie"); +} + static int pcie_phy_poll_ack(void __iomem *dbi_base, int exp_val) { u32 val; @@ -236,35 +244,44 @@ static int imx6_pcie_assert_core_reset(struct pcie_port *pp) struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); u32 val, gpr1, gpr12; - /* - * If the bootloader already enabled the link we need some special - * handling to get the core back into a state where it is safe to - * touch it for configuration. As there is no dedicated reset signal - * wired up for MX6QDL, we need to manually force LTSSM into "detect" - * state before completely disabling LTSSM, which is a prerequisite - * for core configuration. - * - * If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have a strong - * indication that the bootloader activated the link. - */ - regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, &gpr1); - regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, &gpr12); - - if ((gpr1 & IMX6Q_GPR1_PCIE_REF_CLK_EN) && - (gpr12 & IMX6Q_GPR12_PCIE_CTL_2)) { - val = readl(pp->dbi_base + PCIE_PL_PFLR); - val &= ~PCIE_PL_PFLR_LINK_STATE_MASK; - val |= PCIE_PL_PFLR_FORCE_LINK; - writel(val, pp->dbi_base + PCIE_PL_PFLR); - - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, - IMX6Q_GPR12_PCIE_CTL_2, 0 << 10); - } + if (is_imx6qp_pcie(imx6_pcie)) { + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_SW_RST, + IMX6Q_GPR1_PCIE_SW_RST); + } else { + /* + * If the bootloader already enabled the link we need + * some special handling to get the core back into a + * state where it is safe to touch it for + * configuration. As there is no dedicated reset + * signal wired up for MX6QDL, we need to manually + * force LTSSM into "detect" state before completely + * disabling LTSSM, which is a prerequisite for core + * configuration. + * + * If both LTSSM_ENABLE and REF_SSP_ENABLE are active + * we have a strong indication that the bootloader + * activated the link. + */ + regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, &gpr1); + regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, &gpr12); + + if ((gpr1 & IMX6Q_GPR1_PCIE_REF_CLK_EN) && + (gpr12 & IMX6Q_GPR12_PCIE_CTL_2)) { + val = readl(pp->dbi_base + PCIE_PL_PFLR); + val &= ~PCIE_PL_PFLR_LINK_STATE_MASK; + val |= PCIE_PL_PFLR_FORCE_LINK; + writel(val, pp->dbi_base + PCIE_PL_PFLR); + + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6Q_GPR12_PCIE_CTL_2, 0 << 10); + } - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, - IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18); - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, - IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16); + } return 0; } @@ -314,6 +331,14 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) msleep(100); gpiod_set_value_cansleep(imx6_pcie->reset_gpio, 1); } + + if (is_imx6qp_pcie(imx6_pcie)) { + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_SW_RST, 0); + + usleep_range(200, 500); + } + return 0; err_pcie: @@ -616,6 +641,7 @@ static void imx6_pcie_shutdown(struct platform_device *pdev) static const struct of_device_id imx6_pcie_of_match[] = { { .compatible = "fsl,imx6q-pcie", }, + { .compatible = "fsl,imx6qp-pcie", }, {}, }; MODULE_DEVICE_TABLE(of, imx6_pcie_of_match); diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h index 238c8db..5b08e3c 100644 --- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h +++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h @@ -95,6 +95,7 @@ #define IMX6Q_GPR0_DMAREQ_MUX_SEL0_IOMUX BIT(0) #define IMX6Q_GPR1_PCIE_REQ_MASK (0x3 << 30) +#define IMX6Q_GPR1_PCIE_SW_RST BIT(29) #define IMX6Q_GPR1_PCIE_EXIT_L1 BIT(28) #define IMX6Q_GPR1_PCIE_RDY_L23 BIT(27) #define IMX6Q_GPR1_PCIE_ENTER_L1 BIT(26)