From patchwork Mon Mar 20 13:11:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chenhui Sun X-Patchwork-Id: 95532 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp936496qgd; Mon, 20 Mar 2017 06:16:18 -0700 (PDT) X-Received: by 10.55.103.10 with SMTP id b10mr23981813qkc.207.1490015778612; Mon, 20 Mar 2017 06:16:18 -0700 (PDT) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id z21si5376352qkb.50.2017.03.20.06.16.18; Mon, 20 Mar 2017 06:16:18 -0700 (PDT) Received-SPF: pass (google.com: domain of linaro-uefi-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linaro-uefi-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=linaro-uefi-bounces@lists.linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 410BD63E8B; Mon, 20 Mar 2017 13:16:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id A6E9363E80; Mon, 20 Mar 2017 13:15:23 +0000 (UTC) X-Original-To: linaro-uefi@lists.linaro.org Delivered-To: linaro-uefi@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 6544B63E8C; Mon, 20 Mar 2017 13:15:18 +0000 (UTC) Received: from mail-pf0-f181.google.com (mail-pf0-f181.google.com [209.85.192.181]) by lists.linaro.org (Postfix) with ESMTPS id E4DC063E77 for ; Mon, 20 Mar 2017 13:14:59 +0000 (UTC) Received: by mail-pf0-f181.google.com with SMTP id e129so27016308pfh.0 for ; Mon, 20 Mar 2017 06:14:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3eI1vrJ+w4Be8sQaNEn623uVD7hXpSN9IdD1G1n/VIo=; b=U4B7k7qp/lZJOI5myFwB614XZS4CXiRZtb1FpLjgj56NiRZR2vRsi20HZcvIQEJIWL bqbiq4mvxSMXIE5TT9ooZ4uQnrlY9UQR1bK5YK4u2u6Xc6T4GbyXmTpW2WproCOoHUsf p/Gsf6GBJ0O4CqHutENduFh2m7vyVEjhD1sVZagtQZ/VQ6x/q/cD7yy+b3Na/ouc3VN9 P+iHOsNCKr2qcjHu5WiCtEckfqyR2C/8FNBHSC/t4Rel59TPlk3vk0kQVd6UWFkPjcVt iNm1wsjmpNig1rTO8zoDusz/1+zqsJdPlm6ZZJNfyYePs+9jMh/ZAmg5x9ShmOyEnusA tamA== X-Gm-Message-State: AFeK/H3d+u0BzMOK7R3s3Z43LLc0Gi2oj5A0m3RTS9jn3nj2k1izIgjtIR772uyPmr+6LZAy4Rc= X-Received: by 10.98.160.193 with SMTP id p62mr33095385pfl.67.1490015699124; Mon, 20 Mar 2017 06:14:59 -0700 (PDT) Received: from localhost.localdomain ([119.145.15.121]) by smtp.gmail.com with ESMTPSA id a62sm33573787pgc.60.2017.03.20.06.14.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 20 Mar 2017 06:14:58 -0700 (PDT) From: Chenhui Sun To: leif.lindholm@linaro.org, linaro-uefi@lists.linaro.org Date: Mon, 20 Mar 2017 21:11:08 +0800 Message-Id: <1490015485-53685-5-git-send-email-chenhui.sun@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490015485-53685-1-git-send-email-chenhui.sun@linaro.org> References: <1490015485-53685-1-git-send-email-chenhui.sun@linaro.org> Cc: Yi Li , Chenhui Sun , sunchenhui@huawei.com, wanghuiqiang@huawei.com Subject: [Linaro-uefi] [Linaro-uefi v1 04/21] Hisilicon: Add reconfig lane number feature X-BeenThere: linaro-uefi@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: linaro-uefi-bounces@lists.linaro.org Sender: "Linaro-uefi" In some cases, the PCIe device may close part of lanes in config state of LTSSM, the hip06 RC should reconfig lane number and try to linkup again. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Chenhui Sun Signed-off-by: Heyi Guo Signed-off-by: Yi Li --- .../Hi1610/Drivers/PcieInit1610/PcieInitLib.c | 121 ++++++++++++++++++++- Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h | 3 + 2 files changed, 122 insertions(+), 2 deletions(-) diff --git a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c index 57699e0..b45d54f 100644 --- a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c +++ b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c @@ -42,6 +42,7 @@ extern PCIE_DRIVER_CFG gastr_pcie_driver_cfg; extern PCIE_IATU gastr_pcie_iatu_cfg; extern PCIE_IATU_VA mPcieIatuTable; +EFI_STATUS PciePortInit (UINT32 soctype, UINT32 HostBridgeNum, PCIE_DRIVER_CFG *PcieCfg); VOID PcieRegWrite(UINT32 Port, UINTN Offset, UINT32 Value) { RegWrite((UINT64)mPcieIntCfg.RegResource[Port] + Offset, Value); @@ -152,8 +153,123 @@ VOID PcieRxValidCtrl(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port, BOOLEAN } } } +/* + * The ltssm register is assigned in an asynchronous way, the value + * of register may not right in metastable state. + * Read the register twice to get stable value. + */ +VOID PcieGetLtssmValue ( + UINT32 HostBridgeNum, + UINT32 Port, + UINT32* Value +) +{ + UINT32 ValueA; + UINT32 ValueB = 0; + UINT32 Count; + + RegRead(PCIE_APB_SLAVE_BASE_1610[HostBridgeNum][Port] + PCIE_SYS_REG_OFFSET + PCIE_SYS_STATE4_REG, ValueA); + ValueA = ValueA & PCIE_LTSSM_STATE_MASK; + + Count = 0; + while (Count < 2) { + + RegRead(PCIE_APB_SLAVE_BASE_1610[HostBridgeNum][Port] + PCIE_SYS_REG_OFFSET + PCIE_SYS_STATE4_REG, ValueB); + ValueB = ValueB & PCIE_LTSSM_STATE_MASK; + + /* Get the same state in continuous two times*/ + if (ValueA == ValueB) { + break; + } + + /* If the second value not equel to the first, + * we return the second one as the stable + */ + ValueA = ValueB; + Count++; + } + + *Value = ValueB; + + return; + +} + +/* + * In some cases, the PCIe device may close part of lanes in + * config state of LTSSM, the hip06 RC should reconfig lane num + * and try to linkup again. + */ +VOID PcieReconfigLaneNum ( + UINT32 soctype, + UINT32 HostBridgeNum, + UINT32 Port, + PCIE_DRIVER_CFG *PcieCfg +) +{ + EFI_STATUS Status; + UINT32 LtssmStatus; + UINT32 RegVal; + UINT32 LoopCnt = 0; + UINT32 LaneNumCnt = 0; + PCIE_PORT_WIDTH PortWidth = PcieCfg->PortInfo.PortWidth; + + // 500 * 200us = 100ms, so it takes 100 ms must to reconfig lane numbers + while (LoopCnt < 500) { + + /* + * The minimum lanenum is 1, no need to try any more. + */ + if (PortWidth <= 1) { + DEBUG((DEBUG_ERROR, "PcieReconfigLanenum PortWidth <= 1 !\n")); + return; + } + + /* + * Check the lane num config state is normal or not. + */ + PcieGetLtssmValue(HostBridgeNum, Port, &LtssmStatus); + if ((LtssmStatus == PCIE_LTSSM_CFG_LANENUM_ACPT) || (LtssmStatus == PCIE_LTSSM_CFG_COMPLETE)) { + LaneNumCnt++; + } else if (LtssmStatus == PCIE_LTSSM_LINKUP_STATE) { + PcieGetLtssmValue(HostBridgeNum, Port, &LtssmStatus); + if (LtssmStatus == PCIE_LTSSM_LINKUP_STATE) { + break; + } + } else { + LaneNumCnt = 0; + } + + /* + * The lane num config state is abnormal, need to reconfig + * the lane num and try to establish link again. + */ + if (LaneNumCnt > 5) { + /* Disable LTSSM */ + RegRead(PCIE_APB_SLAVE_BASE_1610[HostBridgeNum][Port] + PCIE_CTRL_7_REG, RegVal); + RegVal &= ~(BIT11); + RegWrite(PCIE_APB_SLAVE_BASE_1610[HostBridgeNum][Port] + PCIE_CTRL_7_REG, RegVal); + PcieCfg->PortInfo.PortWidth = (PCIE_PORT_WIDTH)((UINT8)PcieCfg->PortInfo.PortWidth >> 1); + + Status = PciePortInit(soctype, HostBridgeNum, PcieCfg); + if(EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "PcieReconfigLanenum HostBridge %d, Pcie Port %d Init Failed! \n", HostBridgeNum, Port)); + } + return; + } + + LoopCnt++; + /* Pcie 3.0 Spec,part 4.2.6.3.4.1: the Upstream Lanes are permitted + * delay up to 1 ms before transitioning to Configuration.Lanenum.Accept. + * So the delay time 200 us * 5(LanNumCnt) = 1ms, not beyond the reasonable range. + */ + MicroSecondDelay(200); + } + + return ; +} -EFI_STATUS PcieEnableItssm(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port) +EFI_STATUS PcieEnableItssm(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port, PCIE_DRIVER_CFG *PcieCfg) { PCIE_CTRL_7_U pcie_ctrl7; UINT32 Value = 0; @@ -168,6 +284,7 @@ EFI_STATUS PcieEnableItssm(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port) Value |= BIT11|BIT30|BIT31; RegWrite(PCIE_APB_SLAVE_BASE_1610[HostBridgeNum][Port] + 0x1114, Value); (VOID)PcieRxValidCtrl(soctype, HostBridgeNum, Port, 1); + PcieReconfigLaneNum(soctype, HostBridgeNum, Port, PcieCfg); return EFI_SUCCESS; } else @@ -1005,7 +1122,7 @@ PciePortInit ( /* Disable RC Option Rom */ DisableRcOptionRom(soctype, HostBridgeNum, PortIndex, PcieCfg->PortInfo.PortType); /* assert LTSSM enable */ - (VOID)PcieEnableItssm(soctype, HostBridgeNum, PortIndex); + (VOID)PcieEnableItssm(soctype, HostBridgeNum, PortIndex, PcieCfg); if (FeaturePcdGet(PcdIsPciPerfTuningEnable)) { //PCIe will still work even if performance tuning fails, //and there is warning message inside the function to print diff --git a/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h b/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h index 539d567..b750910 100644 --- a/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h +++ b/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h @@ -8982,6 +8982,7 @@ typedef union tagIepMsiCtrlIntStatus #define PCIE_SYS_CTRL28_REG (PCI_SYS_BASE + 0x1c4) #define PCIE_SYS_CTRL29_REG (PCI_SYS_BASE + 0x1c8) #define PCIE_SYS_CTRL54_REG (PCI_SYS_BASE + 0x274) +#define PCIE_SYS_STATE4_REG (PCI_SYS_BASE + 0x31C) #define PCIE_SYS_STATE5_REG (PCI_SYS_BASE + 0x30) #define PCIE_SYS_STATE6_REG (PCI_SYS_BASE + 0x34) #define PCIE_SYS_STATE7_REG (PCI_SYS_BASE + 0x38) @@ -12694,6 +12695,8 @@ typedef union tagPortlogic93 #define PCIE_SUBCTRL_SC_PCIE0_SYS_STATE3_REG (PCIE_SUBCTRL_BASE + 0x6814) #define PCIE_SUBCTRL_SC_PCIE0_SYS_STATE4_REG (PCIE_SUBCTRL_BASE + 0x6818) #define PCIE_LTSSM_STATE_MASK (0x3f) +#define PCIE_LTSSM_CFG_LANENUM_ACPT 0x0a +#define PCIE_LTSSM_CFG_COMPLETE 0x0b #define PCIE_LTSSM_LINKUP_STATE (0x11) #define PCIE_SUBCTRL_SC_PCIE0_AXI_MSTR_OOO_WR_STS0_REG (PCIE_SUBCTRL_BASE + 0x6880) #define PCIE_SUBCTRL_SC_PCIE0_AXI_MSTR_OOO_WR_STS1_REG (PCIE_SUBCTRL_BASE + 0x6884)