From patchwork Wed Aug 6 20:14:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabio Estevam X-Patchwork-Id: 4688341 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CD2C49F401 for ; Wed, 6 Aug 2014 20:15:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 003D6200ED for ; Wed, 6 Aug 2014 20:15:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9B3152017A for ; Wed, 6 Aug 2014 20:15:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754191AbaHFUPJ (ORCPT ); Wed, 6 Aug 2014 16:15:09 -0400 Received: from mail-yk0-f175.google.com ([209.85.160.175]:57259 "EHLO mail-yk0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754124AbaHFUPG (ORCPT ); Wed, 6 Aug 2014 16:15:06 -0400 Received: by mail-yk0-f175.google.com with SMTP id q200so2043396ykb.6 for ; Wed, 06 Aug 2014 13:15:05 -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=QNwE7gLBfvsNUyJco0wLnuq5ILWVmMy0FWufehl4G4g=; b=BwASUpmCIJW3VmajrHT4ZKNbiR1gbEx29LvFMvQfL3ZPjxA/S65x2Hn3T+M+G3gonb bMMEplwzWeBatV/rRfzyjLS8JlzXpW8by6Gc/+0YfjJ3iq+f2+Y7AvY2TDQT4jIWDGZX LnBsE14zQ2XbmQnRMbWsu57Z3ucSSp9WcrS1GTotEKTJ0K2n/mqxWs07Pq4OKPqnrs0o p2iqkYhHijeTVDdTv9Wu6pdJ3RQ2IWn9VAxQKk2TsWkVaUjhmXSweNLLSuGQfZvMWlua wrrcC8eb48V3AQkBX1qH5Rc7w74dQeiR/T9gNdQf+pSM7FmqaNjLD8eqfVhb9615m1M9 qgUw== X-Received: by 10.236.91.171 with SMTP id h31mr20576833yhf.144.1407356105884; Wed, 06 Aug 2014 13:15:05 -0700 (PDT) Received: from localhost.localdomain ([201.82.52.106]) by mx.google.com with ESMTPSA id j21sm3487828yhj.29.2014.08.06.13.15.02 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 06 Aug 2014 13:15:04 -0700 (PDT) From: Fabio Estevam To: bhelgaas@google.com Cc: r65037@freescale.com, shawn.guo@freescale.com, linux-pci@vger.kernel.org, marex@denx.de, l.stach@pengutronix.de, tharvey@gateworks.com, d.mueller@elsoft.ch, Fabio Estevam , Subject: [PATCH] PCI: imx6: fix boot hang when link already enabled Date: Wed, 6 Aug 2014 17:14:39 -0300 Message-Id: <1407356079-28908-1-git-send-email-festevam@gmail.com> X-Mailer: git-send-email 1.9.1 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.5 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=ham 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 From: Fabio Estevam This fixes a boot hang observed when the bootloader already enabled the PCIe link for it's own use. The fundamental problem is that Freescale forgot to wire up the core reset, so software doesn't have a sane way to get the core into a defined state. According to the DW PCIe core reference manual configuration of the core may only happen when the LTSSM is disabled, so this is one of the first things we do. Apparently this isn't safe to do when the LTSSM is in any other state than "detect" as we observe an instant machine hang when trying to do so while the link is already up. As a workaround force LTSSM into detect state right before hitting the disable switch. Tested on a mx6qsabresd board with PCI driver enabled in the bootloader and also with PCI driver disabled in the bootloader. The kernel boots succesfully on both cases now. Cc: # 3.16 Signed-off-by: Lucas Stach Signed-off-by: Fabio Estevam --- drivers/pci/host/pci-imx6.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index a568efa..2fa6d3a 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -49,6 +49,9 @@ struct imx6_pcie { /* PCIe Port Logic registers (memory-mapped) */ #define PL_OFFSET 0x700 +#define PCIE_PL_PFLR (PL_OFFSET + 0x08) +#define PCIE_PL_PFLR_LINK_STATE_MASK (0x3f << 16) +#define PCIE_PL_PFLR_FORCE_LINK (1 << 15) #define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28) #define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c) #define PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING (1 << 29) @@ -214,7 +217,19 @@ static int imx6q_pcie_abort_handler(unsigned long addr, static int imx6_pcie_assert_core_reset(struct pcie_port *pp) { struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); + u32 val; + + regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, &val); + if (val & 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,