From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com []) by mx.groups.io with SMTP id smtpd.web12.7589.1606812881243305129 for ; Tue, 01 Dec 2020 00:54:42 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@os.amperecomputing.com header.s=selector2 header.b=bIBdlhIM; spf=fail (domain: os.amperecomputing.com, ip: , mailfrom: vunguyen@os.amperecomputing.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=AtQf/9Gp/gA7KXYY1aeq2JenclvLbYS18nkNcI/xGqTsciQP4ruSoZEgh9H4BR0e2lOXEcu5EmWW05cCzzOh1XwLjn4fUnbWAM7wXP8GkbkRxqMhTnmy6x4Yc4Cf065CZ7+1IItAi/uEVt9o+hbc7DABmfkFSRE3hqPJ/+40GwBZvLyPGV4WCcWxgfL+oKgPn7rSEB2vCdQu9MVZ+l7Ql308qWfykjcQZubRBq4Jr9sWDylETza/fJUaM+2U7t9sRUjhFEj/sE7gXbVVggaDAYElOoEDtWo+6mAkJkr4WzLYLZcYv/34iMHReT1fMYdCiyd5XTCpI2Zc4WlaSvtZqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=T83qwV6XOiKRtCHXYXjjA6Y5whrfr0TnJuPbEW9YFZE=; b=RqLg+cg2W+epn3raIM+0NoiZImNQqVYpMxjEgp/USfK6BjvGCDhGLKr4BYDerI9aGOt298L8jUDPw7GJNs0nbhuwFo7RJbajUPFCTAiURlglBOZ39WRL/wAkGZkaGxI5tO03PnJaXyvOPzK/BctrFbRQwFeWG1DEQAGH5BBUyTEntgx1AZyb5bkwrQNyb7RVuH58pnTHaEFN3cbp7GhMcGvT7slfFK81fAmoFuPpALDo0gCAe7IYypXAo2xzNvTmY+QYUEaIPf7F9natswBkktrSKApBAULVjB/U/P/uzYBf8aFFRq5Ntyd5qxxXya8EkPnCO4SX2ON5r8xSyTc1Pw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=os.amperecomputing.com; dmarc=pass action=none header.from=os.amperecomputing.com; dkim=pass header.d=os.amperecomputing.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=os.amperecomputing.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=T83qwV6XOiKRtCHXYXjjA6Y5whrfr0TnJuPbEW9YFZE=; b=bIBdlhIMPFI1nN75bTgw4oNQSwZibg0soHXqkZojxIJJFUOY2pMDSTM9FFieJR6C6GdXTr7H2Cxcd1P8+gpE7lhKL11TbTTSpKc/ZfNEc9imOtL2cGqGgQIvdvCjU+druqCPB3oAR/b3kWWN/CJsqOBnYFHdf8GmL7A5NTrfKw0= Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=os.amperecomputing.com; Received: from MN2PR01MB6014.prod.exchangelabs.com (2603:10b6:208:193::12) by MN2PR01MB6062.prod.exchangelabs.com (2603:10b6:208:191::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3611.20; Tue, 1 Dec 2020 08:54:39 +0000 Received: from MN2PR01MB6014.prod.exchangelabs.com ([fe80::1169:ef71:cc90:1b18]) by MN2PR01MB6014.prod.exchangelabs.com ([fe80::1169:ef71:cc90:1b18%7]) with mapi id 15.20.3611.025; Tue, 1 Dec 2020 08:54:39 +0000 From: "Vu Nguyen" To: devel@edk2.groups.io Cc: patches@amperecomputing.com, Vu Nguyen , Leif Lindholm , Ard Biesheuvel , Nate DeSimone Subject: [edk2-non-osi][PATCH 1/2] AmpereAltraBinPkg: Add PciePhyLib library and header Date: Tue, 1 Dec 2020 15:54:08 +0700 Message-Id: <20201201085409.20045-2-vunguyen@os.amperecomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201201085409.20045-1-vunguyen@os.amperecomputing.com> References: <20201201085409.20045-1-vunguyen@os.amperecomputing.com> X-Originating-IP: [118.69.219.201] X-ClientProxiedBy: SG2PR06CA0093.apcprd06.prod.outlook.com (2603:1096:3:14::19) To MN2PR01MB6014.prod.exchangelabs.com (2603:10b6:208:193::12) Return-Path: vunguyen@os.amperecomputing.com MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from sw003.amperecomputing.com (118.69.219.201) by SG2PR06CA0093.apcprd06.prod.outlook.com (2603:1096:3:14::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3632.17 via Frontend Transport; Tue, 1 Dec 2020 08:54:36 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 32449ec8-9534-475b-f894-08d895d6bc6e X-MS-TrafficTypeDiagnostic: MN2PR01MB6062: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:72; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: GOumYzyKzhhCkRI2VdGozukjIgAvPAIrC7FCkrED5f0w8HudxLAHVKgTceEZ3mqZDLJUhBoxBKjh1p1c9jH73kvU405czOSJPX/LLh8tZw7sb3ClpYUAp9phWgIcrST+kOntednj1XDmFXHl/PyIsxeDVmL/JQI6S9ls4jLi4+36FnZYNRPW64X70qnBejLAwvCwEllDfynnGhOHRHJKfP1FCQAnj0Rak4vhQVWm+L2/doqU6X4Sri/PBSYoKDotuxF4cV1EucXtXJITYS6vSGh6jWQL9O2jZ74XyMDdLgC1wZD2mG0ReNzA+M6kXcBtQvdFq0ndGWoztoIk1BgM5Q== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR01MB6014.prod.exchangelabs.com;PTR:;CAT:NONE;SFS:(4636009)(136003)(366004)(39850400004)(396003)(346002)(376002)(8936002)(19627235002)(6486002)(6506007)(5660300002)(52116002)(6512007)(66556008)(66946007)(1076003)(66476007)(6916009)(6666004)(2906002)(316002)(30864003)(26005)(2616005)(956004)(83380400001)(86362001)(54906003)(478600001)(8676002)(4326008)(16526019)(186003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?/rC89Cy/aglWdZ1znZtt6mdDNbZ+wXjkSCUynnOMo6zut4LRPygi2ke3lcL8?= =?us-ascii?Q?PJpFXlOk26ca0DKWyQXO0JSrdTUAhW14CfL1r/l5i33HYR9EMIIFsNHn3Llo?= =?us-ascii?Q?dO8K2wILNYTzQd+OsbF/u0vBjXnlXVmf0knDs1tlQHNjRybL1l40TwXsJFaj?= =?us-ascii?Q?giOuqmfIAIaNiZH4bUyatfbhJ6VcDgzEJJQhQypJD0vnyoeimSXit8FBRDI4?= =?us-ascii?Q?oK/9RkyTbMYrREhSo9fo7IkzXGowxlgBtvtC9pwx6i2UgCJRFooaYeR+gkdW?= =?us-ascii?Q?Z4Wogr3OXbz9gpL8ddCJh5Kdg+y1KduxJMvLCKhzKO5tIr4lwm6+koJyn9Og?= =?us-ascii?Q?LDIbCfgVYGPsvWx4PEjDolkW10IpLU4G3jY/d564GQWjXM6wSPhpElfIes+Z?= =?us-ascii?Q?61I1MAN0+Nn0C3FVAWieuiJKBOzGDnG1IE4BvZDiQJcrbZMqujcrLl+EcutJ?= =?us-ascii?Q?0j0IvloYFl7e3Z+mPhDgYtdW/gC5RbBIQKcyh+pVnkyuXa2ymRTxNQ+T8Jsd?= =?us-ascii?Q?9bHdRdoeWLYv5En2Hj9lel+arBIMQJZcmqKHkRc4dCMO+hz81C1nMaMfVL0I?= =?us-ascii?Q?xCRzc4k4Ee/yrURaeq2p8/5NT4YK/T261cN8lGL7rVW5fuKXK2NC+i461W6K?= =?us-ascii?Q?h1getMJbqCRIFUdTHKzKxdAJQ/C7j3+1anUAXvf6PX/07hTo+S4yXt5S7jWy?= =?us-ascii?Q?3PKZfHcK+rOhArrhdu3GvWwICl/Zuz3OFvdcebPwer71V50u/ELmZuOF2r6x?= =?us-ascii?Q?OtMKq/X/lYRWu/eCsE2LTZgSjNH9Yv9Jc7gCG2CGRgIloXJWS9bLtLvWXGXL?= =?us-ascii?Q?pmEfvcrP0KEmwGmH02IMRQpY01KtOY0tXDwA0yVkJgs0fE1AZDiLVBxf9pM1?= =?us-ascii?Q?wDindN4ePRz/p3FBf5JzE30FEJvPkxIl6mY0bunPu3icRuD+/RYSJQD3DYrX?= =?us-ascii?Q?XfQxvIxPHa9tiycrjO5Nhg+wzlVzpQIi5xa/ejOk6HLih6eP0qNwaTh+65CT?= =?us-ascii?Q?bI6t?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: 32449ec8-9534-475b-f894-08d895d6bc6e X-MS-Exchange-CrossTenant-AuthSource: MN2PR01MB6014.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Dec 2020 08:54:39.3032 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3bc2b170-fd94-476d-b0ce-4229bdc904a7 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ZbSdfC7vDblQkzVZXDhwPtDg6EsIrJs3jHvQ/zP1K3YEQ4+JZ7AC6DZsf1edcwJ+u4QFFHby45xKssKaFBQwTQAnWwfu1aU5YR2d61UjRoc6w7PZCYaPxYSOcYtLpX+m X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR01MB6062 Content-Type: text/plain Initialization library for PCIe PHY on Ampere Altra. Cc: Leif Lindholm Cc: Ard Biesheuvel Cc: Nate DeSimone Signed-off-by: Vu Nguyen --- Silicon/Ampere/License.txt | 25 +++ .../Ampere/AmpereAltraBinPkg/Ac01BinPkg.dec | 16 ++ .../Library/PciePhyLib/PciePhyLib.inf | 23 +++ .../Include/Library/PciePhyLib.h | 165 ++++++++++++++++++ .../Library/PciePhyLib/PciePhyLib.lib | Bin 0 -> 26026 bytes 5 files changed, 229 insertions(+) create mode 100644 Silicon/Ampere/License.txt create mode 100644 Silicon/Ampere/AmpereAltraBinPkg/Ac01BinPkg.dec create mode 100644 Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.inf create mode 100644 Silicon/Ampere/AmpereAltraBinPkg/Include/Library/PciePhyLib.h create mode 100644 Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.lib diff --git a/Silicon/Ampere/License.txt b/Silicon/Ampere/License.txt new file mode 100644 index 000000000000..2fd43292fa64 --- /dev/null +++ b/Silicon/Ampere/License.txt @@ -0,0 +1,25 @@ +Copyright (c) 2020, Ampere Computing LLC. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/Silicon/Ampere/AmpereAltraBinPkg/Ac01BinPkg.dec b/Silicon/Ampere/AmpereAltraBinPkg/Ac01BinPkg.dec new file mode 100644 index 000000000000..2a8ec5e693ec --- /dev/null +++ b/Silicon/Ampere/AmpereAltraBinPkg/Ac01BinPkg.dec @@ -0,0 +1,16 @@ +## @file +# +# Copyright (c) 2020, Ampere Computing LLC. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION = 0x0001001B + PACKAGE_NAME = Ac01BinPkg + PACKAGE_GUID = 04F7CB64-0F97-4D05-86B8-34987F4E1B21 + PACKAGE_VERSION = 0.1 + +[Includes] + Include diff --git a/Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.inf b/Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.inf new file mode 100644 index 000000000000..84b1b58ed58c --- /dev/null +++ b/Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.inf @@ -0,0 +1,23 @@ +## @file +# +# Copyright (c) 2020, Ampere Computing LLC. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = PciePhyLib + FILE_GUID = F2AD0AD0-D4B6-11E3-9C1A-0800200C9A66 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PciePhyLib + +[Binaries.AArch64] + LIB|PciePhyLib.lib|* + +[Packages] + MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec diff --git a/Silicon/Ampere/AmpereAltraBinPkg/Include/Library/PciePhyLib.h b/Silicon/Ampere/AmpereAltraBinPkg/Include/Library/PciePhyLib.h new file mode 100644 index 000000000000..54680f304677 --- /dev/null +++ b/Silicon/Ampere/AmpereAltraBinPkg/Include/Library/PciePhyLib.h @@ -0,0 +1,165 @@ +/** @file + + Copyright (c) 2020, Ampere Computing LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PCIE_PHY_LIB_H__ +#define __PCIE_PHY_LIB_H__ + +#define PHY_TX_PARAM_SIZE 2 +#define PHY_RX_PARAM_SIZE 2 + +#define BUG_67112 1 +#define UPDATE_SRAM 0 + +#define MULTWRITE_ENABLE 0 +#define MULTI_WR_EN 0 +#define PHY_N_ADDR_OFFSET 0x40000 +#define SNPS_PHY0_BASE_ADDR 0x100000 +#define SNPS_PHY1_BASE_ADDR (SNPS_PHY0_BASE_ADDR + PHY_N_ADDR_OFFSET) +#define SNPS_PHY2_BASE_ADDR (SNPS_PHY1_BASE_ADDR + PHY_N_ADDR_OFFSET) +#define SNPS_PHY3_BASE_ADDR (SNPS_PHY2_BASE_ADDR + PHY_N_ADDR_OFFSET) + +#define BROADCAST_PMA(Src) ((Src | (0x5 << 12)) * 4) +#define BROADCAST_RAW_PCS(Src) ((Src | (0x6 << 12)) * 4) +#define BROADCAST_RAW_PCS_AON(Src) ((Src | (0x7 << 12)) * 4) + +#define PHY_CALIB_TO_VALUE 1000 +#define SRAM_INIT_TO_VALUE 1000 +#define MRDY_DELAY 10 + +#define SRAM_BYPASS_0 0 +#define SRAM_BYPASS_1 1 +#define SRAM_BYPASS_2 2 +#define SRAM_BYPASS_3 3 + +#define SRAM_BOOTLOAD_BYPASS_0 0x1 +#define SRAM_BOOTLOAD_BYPASS_1 0x2 +#define SRAM_BOOTLOAD_BYPASS_2 0x4 +#define SRAM_BOOTLOAD_BYPASS_3 0x8 + +#define SRIS_MODE_EN 0 +#define CLK_REF_SEL 0 +#define CLK_SSC_SEL 1 + +#define CRP_SEL 1 +#define MAX_PHY 3 + +#define LANE_PER_PHY_NUM_MAX 4 + +#define HOST_SECURE_ACCESS(Addr) (UINT64)(Addr | 0x40000000000000) +#define STARTING_SRAM_ADDRESS 0x130000 + +/* + * PCIe PHY error code + */ +typedef enum { + PHY_SRAM_UPDATE_FAIL = -1, + PHY_INIT_PASS = 0, + PHY_ROM_ECC_FAIL, + PHY_SRAM_ECC_FAIL, + PHY_CALIB_FAIL, + PHY_CALIB_TIMEOUT, + PHY_PLL_FAIL +} PHY_STATUS; + +typedef enum { + PHY_DBG_ERROR = 0x0001, + PHY_DBG_INFO = 0x0002, + PHY_DBG_WARN = 0x0004, + PHY_DBG_VERBOSE = 0x0008, + GEN1 = 0, + GEN2 = 1, + GEN3 = 2, + GEN4 = 3, + CCIX = 4 +} PHY_DBG_FLAGS; + +typedef struct { + UINT8 IsCalBySram; + UINT32 PllSettings; + UINT64 TuneTxParam[PHY_RX_PARAM_SIZE]; + UINT64 TuneRxParam[PHY_TX_PARAM_SIZE]; +} PHY_SETTING; + +/** + * struct serdes_plat_resource - Serdes Platform Operations + * @Puts: Prints string to serial console + * @PutInt: Prints 32-bit unsigned integer to serial console + * @PutHex: Prints 32-bit unsigned hex to serial console + * @PutHex64: Prints 64-bit unsigned hex to serial console + * @DebugPrint: Prints formated string to serial console + * @MmioRd: Reads 32-bit unsigned integer + * @MmioWr: Writes 32-bit unsigned integer + */ +typedef struct { + VOID (*Puts)(CONST CHAR8 *Msg); + VOID (*PutInt)(UINT32 Val); + VOID (*PutHex)(UINT32 Val); + VOID (*PutHex64)(UINT64 Val); + INT32 (*DebugPrint)(CONST CHAR8 *Fmt, ...); + VOID (*MmioRd)(UINT64 Addr, UINT32 *Val); + VOID (*MmioWr)(UINT64 Addr, UINT32 Val); + VOID (*UsDelay)(UINT32 Val); +} PHY_PLAT_RESOURCE; + +typedef struct { + UINT64 SdsAddr; /* PHY base address */ + UINT64 PcieCtrlInfo; /* PCIe controller related information + * BIT0-1: SoC revision + * 0: Ampere Altra, 1: Ampere Altra Max, 2: Siryn + * BIT2 : SocketID (0: Socket0, 1: Socket1) + * BIT3 : Reserved + * BIT4-6: Root Complex context (RCA0/1/2/3 or RCB0/4/5/6) + * BIT7 : Reserved + * BIT8-9: PHY Numbers within RCA/RCB [0 to 3 each controls 4 lane] + * 0: x16, 1: x8 , 2:x4, 3: 0x2 + * BIT10-11 : Gen + * 0: Gen1, 1: Gen2, 2: Gen3, 3: Gen4 + ESM + * BIT13-15 : Setting configuration selection + */ + PHY_SETTING PhySetting; /* PHY input setting */ + PHY_PLAT_RESOURCE *PhyPlatResource; /* Debug & misc function pointers */ + PHY_DBG_FLAGS Debug; +} PHY_CONTEXT; + +/* + * Input: + * Ctx - Serdes context pointer + * + * Return: + * PHY_STATUS - Return status + */ +PHY_STATUS +SerdesSramUpdate ( + PHY_CONTEXT *Ctx + ); + +/* + * Input: + * Ctx - Serdes context pointer + * + * Return: + * PHY_STATUS - Return status + */ +PHY_STATUS +SerdesInitClkrst ( + PHY_CONTEXT *Ctx + ); + +/* + * Input: + * Ctx - Serdes context pointer + * + * Return: + * PHY_STATUS - Return status + */ +PHY_STATUS +SerdesInitCalib ( + PHY_CONTEXT *Ctx + ); + +#endif diff --git a/Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.lib b/Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.lib new file mode 100644 index 0000000000000000000000000000000000000000..88aaf2cd4adc30bba4bd3b5bb078e1fa0579825d GIT binary patch literal 26026 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 eG5wdzd3Q$pkELqYe@$;=$r literal 0 HcmV?d00001 -- 2.17.1