From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=104.47.36.78; helo=nam02-sn1-obe.outbound.protection.outlook.com; envelope-from=vabhav.sharma@nxp.com; receiver=edk2-devel@lists.01.org Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1nam02on0078.outbound.protection.outlook.com [104.47.36.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id C9446222CB309 for ; Thu, 21 Dec 2017 22:45:38 -0800 (PST) Received: from CY1PR03CA0011.namprd03.prod.outlook.com (10.174.128.21) by CY4PR03MB2694.namprd03.prod.outlook.com (10.173.43.137) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.323.15; Fri, 22 Dec 2017 06:50:25 +0000 Received: from BN1BFFO11FD044.protection.gbl (2a01:111:f400:7c10::1:142) by CY1PR03CA0011.outlook.office365.com (2603:10b6:600::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.345.14 via Frontend Transport; Fri, 22 Dec 2017 06:50:25 +0000 Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; nxp.com; dkim=none (message not signed) header.d=none;nxp.com; dmarc=fail action=none header.from=nxp.com; Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; Received: from tx30smr01.am.freescale.net (192.88.168.50) by BN1BFFO11FD044.mail.protection.outlook.com (10.58.144.107) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.302.6 via Frontend Transport; Fri, 22 Dec 2017 06:50:10 +0000 Received: from uefi-OptiPlex-790.ap.freescale.net ([10.232.132.56]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id vBM6oHF2022495; Thu, 21 Dec 2017 23:50:22 -0700 From: Vabhav To: , , , Date: Fri, 22 Dec 2017 00:18:27 +0530 Message-ID: <1513882109-14295-2-git-send-email-vabhav.sharma@nxp.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1513882109-14295-1-git-send-email-vabhav.sharma@nxp.com> References: <1513882109-14295-1-git-send-email-vabhav.sharma@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131583990108433390; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(336005)(7966004)(396003)(376002)(346002)(39380400002)(39860400002)(2980300002)(1110001)(1109001)(339900001)(199004)(189003)(68736007)(966005)(8936002)(5660300001)(6306002)(356003)(77096006)(59450400001)(104016004)(47776003)(4326008)(53376002)(53946003)(305945005)(15188155005)(8676002)(2906002)(36756003)(498600001)(53936002)(85426001)(2201001)(316002)(16799955002)(97736004)(106466001)(51416003)(81166006)(2950100002)(50466002)(50226002)(105606002)(48376002)(551934003)(16200700003)(110136005)(76176011)(86362001)(81156014)(575784001)(16586007)(54906003)(8656006)(559001)(579004)(569006); DIR:OUT; SFP:1101; SCL:1; SRVR:CY4PR03MB2694; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1BFFO11FD044; 1:/eA815DLMLRRS9FDmXnJMKziDwCX9S54zjRgr0InxriVT4BfFh3FZwC03LdRyLA8hROCGeYJwlPmqnx0t7qeWKP8iMnnzTheIKuAesRLE8rpV4MyUIXz97Q2PoxXz9pi MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d92b48c6-6ae4-4d41-abee-08d549083f01 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(5600026)(4604075)(4534020)(4628075)(201703131517081)(2017052603307); SRVR:CY4PR03MB2694; X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2694; 3:HoTFEAA1UfVxLBxncaErQ8yoWfFcA4Om1GHFuiwVRZlK1ZYM7yiWKbC8jQcFmaD1QICi7QNPBaYRI972Hw4ibsBri4qK9trgpERuEXGEIG7iU3fUQmwTIKn1P4VLglkY/LPMRpKoMv3ujIL5GykHRiJzWumZtUh295kq+PaZ4yFaxQTs1ZT3v0aXnAVPRNZ94cpftoS9+DCje7J1lQw++0j6jsipAN5dM3LR4dNiOhv7ufKwqlcZN4S0gCytMYOpvbiceiMwUzN9I7vhTDUaiVTA2eDPeONO164TervL6jW0YFFQSyOVx2KKTN491fjxDbeVrDbZmF91C6KjO5duwPhzAPPYZWS0JGcUs0LKlFg=; 25://pTgf19gK5z5jg4BcVN8nCv9IVGh1wD37hLxDiWr/a53G4Hpg3UpIe4VEzi+yq434uwhJ9+We5S1qG6pq+QUH8/0e116nk2IsgKfP38whYioudHvw5fDdjzoIaVyUsVCr7cZksMdtYdNccDuLS2BRYB6ERb44u9oCzV83LsI7Uipdu0krm7QxYNIJcpQX6YWH2G0mMMvCFDPdjJDxUfacWaOZpXow3yK8NcJooEEuWh6QAZIPXFML0EaoCGxmApgyVgjQ2oPbP3dYzCLvXvk/Uhx069KiF9kmnM0lgnWoBbJUXLMy/3ST5Cqz3aU9mnZHgo5N1WAoYwmf448QZ2Cw== X-MS-TrafficTypeDiagnostic: CY4PR03MB2694: X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2694; 31:H4LQ9w7DGvo+tlThNSRFOt3B5CvI17oxmozv6QSMyPcNPDGvReR4qvmszrTTgUkAGd4lgt7MDcWsvj6S1IcSAiGyVXZG4LZTcpaMY0tKpJaRhYaHxSi7uyp/H+SVj3kFZZo4yWzqGA8UXU2r5iYg4O95TY3L2nI3hUH5jSB0ycPNQTJUf2Brzs1zWQLmyIKPymEEqyb9AedDhdgcbENUbPTXQpskxk/tNVomVieSq4o=; 4:g63euF51MkC8c7sANcBL4znKgt0j8QdSDAF3DR5t1lf7EIR3pSz++kBPzw7iYNRrU0TO57EFwuzdV0gqC5BIDN378ENDwyTwNjUI2ECmvprNvScc08PcqSrk3C4ObzATgPbh7gw13X3r1sAfnWwLWpQsMwOiSgmF3RdqR0/pIVQNKiJiJyGPbfiyemAvwkEVnRTjR43hKBgAf5VNvU73LSjI2gBUHKdJzzPm3/lhp23MkcJLXCuuiXb8s4ArTbEpcP7DCT5p5ezuISwJRiJJl1Ob6prcUkSm6jTV0WhuWI2O4XCIl7V5hQdAoDU1Azdb X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6095135)(2401047)(8121501046)(5005006)(3231023)(93006095)(93001095)(10201501046)(3002001)(6055026)(6096035)(20161123563025)(201703131430075)(201703131433075)(201703131441075)(201703131448075)(201703161259150)(20161123559100)(20161123556025)(20161123561025)(20161123565025)(201708071742011); SRVR:CY4PR03MB2694; BCL:0; PCL:0; RULEID:(100000803101)(100110400095)(400006); SRVR:CY4PR03MB2694; X-Forefront-PRVS: 05299D545B X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY4PR03MB2694; 23:JqJwAEIziqJGUAf1J5rK6d9Pkq41da9OsmsljTSgE?= =?us-ascii?Q?S9ze2I9cTEHHtRkS0osIsvhFaieG6lwmTRuRjYUNMVdZykebtdrlkXAGf1Ic?= =?us-ascii?Q?W1UlSY3L4HACEyB6auppa1S4cV+fv5PikgqWdRwBt2YH8r7kf2bo+xZ+hZFq?= =?us-ascii?Q?RKlQC0+7B7vsQ3ZW7PjHUfS3gepvmPKGFHNqjoJ5Dnn2d5xUjoh2i1OMENQF?= =?us-ascii?Q?aycVdwpAWr+tIjWGS/VrlbzoWMYLdeCufQ2qof4qDlpzfByZlBj6eCJ2PyOC?= =?us-ascii?Q?CKgvYZXIiXJ2m51JoJ/p0hOyeJUTG1yPu+G0VU4NlNAWqbL4yJn6tPsQqjys?= =?us-ascii?Q?7ETeJGgq8KfSxgZE0hUOV7ykLiF4nlnIgxOLsZMIucHfxt9q3Qw1h4YDRb49?= =?us-ascii?Q?OasW4ZRkw37MMsqXyKEEZptQxB3tolWPwQudwj9Tu4W38ryTZnbC+3u2fjVP?= =?us-ascii?Q?QpYr7ahMiCzhCkpufB0EGvKEraR/Lh0IBmWZYQ2T30nGOW6DejAQw+OB2jDf?= =?us-ascii?Q?E+R3r8WRjOFXx57w2Q1i6yWuHWQ9qpSUD9kakq8bf97CUim1bV1AIbsVZ6Fx?= =?us-ascii?Q?4PF18ANilmG8mdyRaAVYf55hNONfWHzWl++0r6QA2NmuABJ1URQGyseJ9Jzy?= =?us-ascii?Q?ci14Q0XvvO1x/v/p2lc0ZARrYXMcGrfhPHkG1jByZgkj5LCYMe7rzaRqaHam?= =?us-ascii?Q?N+x+4/Js6kUHBatcFVrgunJecclabJuPBE93XdFQqWPlbsI94HVmiHvwORuE?= =?us-ascii?Q?mKJ3OMe8o3RIhc14HzUriPj522tonZD1L2YmB8NxpQY+dwfWwoipA/ADoDKQ?= =?us-ascii?Q?IEE/qRlcmJHoRPEMoVYzYIeYXcrZhKzL/IieL0SYD3oqBT/wcQHcazPoQhIu?= =?us-ascii?Q?UrgnrXjbWMlgQ5n2xklzmVts45bzOYJ2Aq0o7fgr3z7l2hxSToEFIN0pDV3/?= =?us-ascii?Q?+WsAW/CMNlMHE3BlbsI+l95uiWu0TQqcLUaedbPbXKCQauNmdBnBeUoZE0lp?= =?us-ascii?Q?Cxy4KRGfGjtRfjcyOSbxF+k2BRJgVydGu+4EujB5w9qACltimYpKiGKHxMDJ?= =?us-ascii?Q?2v/XCLBDxqVFZCLweECNFIZMRJhpmxxiwkC+WNg64OV/+d7ZDbK5zrIP8X+8?= =?us-ascii?Q?ULZiJ3fm8MHPHtKcIfHxbA/0coFmbJYpNPumF8V68iXvRIA0hEhv2qwsNM6a?= =?us-ascii?Q?IL2JtEqltPPXrIfXzmM7jL4XAUjVgrm43YgO8Px/hvRM2UCdOM7VJLJkZtno?= =?us-ascii?Q?8Xfj9gThfbFVCh4ld1gjJTu487VR27Tw3yu0KaSdi1PhQi/w9fHqJJr9xjli?= =?us-ascii?Q?vL2vC6f8K8OlCJPfTkhbD57c8RnHrT/BeHenWudkEzhVRnci549x1vZifaEY?= =?us-ascii?Q?GDp6LjrHQ0JXr6GgQ9LcX2Nnok=3D?= X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2694; 6:grssZUyUgAcb7kOuskT+aSW6agLTHfCQ+1bdouR5mPsBZXM/LYSFAnPcwQx22+7SWXWC204yRoCVJ6sHVZqXb5B2TY/svmwxg1YtJGtyy6rh/xVonz4ScLQmW+GhBNS0/mb+j1OJEx9ynLOYmrnlXc7Djwe2Jw8oqJ5KZf7dzUbr+bGR+i0r7sF2UkjAD+/B5Lv7HuiBUZMcCxcjZhuqJZs3KO22NEDlm79ilzufOgjnQLAJXbw7GOAYIKHnzYosiFtWaB1kPb2IfPFoFl68DTWBYuvKwb+QO8L9Y33goNw1aLVbIGIjoRnhdPtkxUttWv6aFkX4iwXgH1Cf6W6Wx1QybIH2J3JgnKoniiVhwEk=; 5:cDGAuxP9giNjid+Cp7IhNR/30rlM0DkYAjTP8XbjABG+/gCJ+lvLjZbs5++eGl7GvQGWOeUP9hHz+yLXoChsccAkCvXE7qU0OmWxlCZPh7PIhKRg0ZoSv2v6f6WZhTfFoOyPS/2AyrnAAnLUKngtpd1eZ1Ry4xicXC21lTncc+k=; 24:7IbyzMcytDRbYPI9V1+z7tFNkf3bcoW1SxepfjA1dLLDsiSBnZDE8xdTFzpygS32vYWAx7e+EjDatntw+ZM8W+B/KY9XvoBNgfScpjxV2To=; 7:ykgARpq1UX4jAAvHp68L7b8ZgdgDOwzuh+toEAErsyVwBlts3RkUf9jMnWoLSJlV3Lz3vOI8PwgkWmM2xLGdY6v0JOi/D5V7dWK7d2SsDZydCEQEoP9aoYJt7l2+ho+j66k3iPxKlUmj7NLzGt8j6+b1JAlbZk/XMm91co/MTFlDop8TPQLnyRVTuG/kRULUN4wR+NrUbjJNXW7r943vV4PTA2P33O+CH4s/T9fbjqSMcZSHfILGKsoEsHAYjUEq SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Dec 2017 06:50:10.6561 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d92b48c6-6ae4-4d41-abee-08d549083f01 X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR03MB2694 Subject: [PATCH edk2-platforms 1/3] Platform/NXP : Add PCI Host Bridge Libary X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Dec 2017 06:45:39 -0000 Content-Type: text/plain Added PCIe Host Bridge Library to provide helper functions which will be used by PCIe Host bridge Dxe Driver Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Vabhav --- Platform/NXP/Include/PciCntrlLib.h | 323 +++++++++++ Platform/NXP/Include/PciLib.h | 414 ++++++++++++++ Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c | 628 +++++++++++++++++++++ .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 49 ++ Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c | 331 +++++++++++ 5 files changed, 1745 insertions(+) create mode 100644 Platform/NXP/Include/PciCntrlLib.h create mode 100644 Platform/NXP/Include/PciLib.h create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c diff --git a/Platform/NXP/Include/PciCntrlLib.h b/Platform/NXP/Include/PciCntrlLib.h new file mode 100644 index 0000000..c8001d9 --- /dev/null +++ b/Platform/NXP/Include/PciCntrlLib.h @@ -0,0 +1,323 @@ +/** PciCntrlLib.c + The Header file of the Pci Controller Driver + + Some part of code is inspired from EDK II, file: + MdePkg/Include/Library/PciLib.h + + Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved + Copyright 2017 NXP + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PCI_CNTRL_H_ +#define _PCI_CNTRL_H_ + +#include +#include + +#define SDRAM_BASE 0x80000000 + +// LUT registers +#define LS_PCIE_LUT_BASE PcdGet64 (PcdPcieLutBase) +#define LS_PCIE_LUT_DBG PcdGet64 (PcdPcieLutDbg) +#define PCIE_LUT_UDR(n) (0x800 + (n) * 8) +#define PCIE_LUT_LDR(n) (0x804 + (n) * 8) +#define PCIE_LUT_ENABLE (1 << 31) + +#ifndef LS_PCI_MEMORY_BUS +#define LS_PCI_MEMORY_BUS SDRAM_BASE +#endif + +#ifndef LS_PCI_MEMORY_PHYS +#define LS_PCI_MEMORY_PHYS SDRAM_BASE +#endif + +#ifndef LS_PCI_MEMORY_SIZE +#define LS_PCI_MEMORY_SIZE (2 * 1024 * 1024 * 1024UL) +#endif + +/* iATU registers */ +#define LS_PCIE_ATU_VIEWPORT 0x900 +#define LS_PCIE_ATU_REGION_INBOUND (0x1 << 31) +#define LS_PCIE_ATU_REGION_OUTBOUND (0x0 << 31) +#define LS_PCIE_ATU_REGION_INDEX0 (0x0 << 0) +#define LS_PCIE_ATU_REGION_INDEX1 (0x1 << 0) +#define LS_PCIE_ATU_REGION_INDEX2 (0x2 << 0) +#define LS_PCIE_ATU_REGION_INDEX3 (0x3 << 0) +#define LS_PCIE_ATU_REGION_INDEX4 (0x4 << 0) +#define LS_PCIE_ATU_CR1 0x904 +#define LS_PCIE_ATU_TYPE_MEM (0x0 << 0) +#define LS_PCIE_ATU_TYPE_IO (0x2 << 0) +#define LS_PCIE_ATU_TYPE_CFG0 (0x4 << 0) +#define LS_PCIE_ATU_TYPE_CFG1 (0x5 << 0) +#define LS_PCIE_ATU_CR2 0x908 +#define LS_PCIE_ATU_ENABLE (0x1 << 31) +#define LS_PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) +#define LS_PCIE_ATU_LOWER_BASE 0x90C +#define LS_PCIE_ATU_UPPER_BASE 0x910 +#define LS_PCIE_ATU_LIMIT 0x914 +#define LS_PCIE_ATU_LOWER_TARGET 0x918 +#define LS_PCIE_ATU_BUS(x) (((x) & 0xff) << 24) +#define LS_PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) +#define LS_PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) +#define LS_PCIE_ATU_UPPER_TARGET 0x91C + +/** DBI Read-Only Write Enable Register: Pg 1518 RM rev B + Set bit 0 of this register as 1. + Write to RO Registers Using DBI. + When you set this field to "1", then some RO and HwInit bits are writable + from the local application through the DBI. + **/ +#define LS_PCIE_DBI_RO_WR_EN 0x8bc + +#define LS_PCIE_LINK_CAP 0x7c +#define LS_PCIE_LINK_SPEED_MASK 0xf +#define LS_PCIE_LINK_STA 0x82 + +#define LS_LTSSM_STATE_MASK 0x3f +#define LS_LTSSM_PCIE_L0 0x11 // L0 state + +#define LS_PCIE_DBI_SIZE 0x100000 // 1M + +#define PCI_CLASS_REVISION 0x08 // High 24 bits are class,low 8 revision +#define PCI_REVISION_ID 0x08 // Revision ID +#define PCI_CLASS_PROG 0x09 // Reg. Level Programming Interface +#define PCI_CLASS_DEVICE 0x0a // Device class +#define PCI_CLASS_CODE 0x0b // Device class code +#define PCI_CLASS_BRIDGE_PCI 0x0604 + +/** + Macro that converts PCI Bus, PCI Device, PCI Function and PCI Register to an + address that can be passed to the PCI Library functions. + + @param Bus PCI Bus number. Range 0..255. + @param Device PCI Device number. Range 0..31. + @param Function PCI Function number. Range 0..7. + @param Register PCI Register number. Range 0..255 for PCI. Range 0..4095 + for PCI Express. + + @return The encoded PCI address. + **/ +#define PCI_LIB_ADDRESS(Bus,Device,Function,Register) \ + (((Register) & 0xfff) | (((Function) & 0x07) << 12) | (((Device) & 0x1f) << 15) | (((Bus) & 0xff) << 20)) + +#define PCI_BUS_DEV(Bus,Device,Function) \ + ((((Function) & 0x07) << 16) | (((Device) & 0x1f) << 19) | (((Bus) & 0xff) << 24)) + +/** + Function to set-up PCIe region +**/ +VOID +PciSetRegion ( + IN PciRegion *Reg, + IN PciAddrT BusStart, + IN PhysAddrT PhysStart, + IN PciSizeT Size, + IN UINTN Flags +); + +/** + Function to setup PCIe space(Mem,I/O,Configuration) +**/ +VOID +SetLSPcieInfo ( + IN LsPcieInfo *PcieInfo, + IN UINTN Num +); + +/** + Function to check PCIe link state +**/ +INTN +PcieLinkState ( + IN LsPcie *Pcie +); + +/** + Helper Function to check PCIe link state + Downgrade the speed to gen1 +**/ +INTN +PcieLinkUp ( + IN LsPcie *pcie +); + +/** + Function to set up PCIe (cfg0)configuration space +**/ +VOID +PcieCfg0SetBusdev ( + IN LsPcie *Pcie, + IN UINT32 BusDev +); + +/** + Function to set up PCIe (cfg1)configuration space +**/ +VOID +PcieCfg1SetBusdev ( + IN LsPcie *Pcie, + IN UINT32 BusDev +); + +/** + Function to set up iATU for outbound PCIe transactions +**/ +VOID +PcieIatuOutboundSet ( + IN LsPcie *Pcie, + IN UINT32 Idx, + IN UINT32 Type, + IN UINT64 Phys, + IN UINT64 BusAddr, + IN UINT64 Size +); + +EFI_STATUS +PciSkipDev ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev +); + +/** + Function to verify if PCIe address space is valid +**/ +EFI_STATUS +PcieAddrValid ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev +); + +/** + Function to read value(32-bit) from PCI space +**/ +EFI_STATUS +PcieReadConfig ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Where, + IN OUT UINT32 *Val +); + +/** + Function to read byte from PCI space +**/ +EFI_STATUS +PcieReadConfigByte ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + IN OUT UINT8 *Val +); + +/** + Function to read word from PCI space +**/ +EFI_STATUS +PcieReadConfigWord ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + IN OUT UINT16 *Val +); + +/** + Function to write byte in PCI space +**/ +EFI_STATUS +PcieWriteConfigByte ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + OUT UINT8 Val +); + +/** + Function to write word in PCI space +**/ +EFI_STATUS +PcieWriteConfigWord ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + OUT UINT16 Val +); + +/** + Function to write value(32-bit) in PCI space +**/ +EFI_STATUS +PcieWriteConfig ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Where, + IN UINT32 Val +); + +/** + Function for setting up internal Address translation unit(ATU) +**/ +VOID +PcieSetupAtu ( + IN LsPcie *Pcie, + IN LsPcieInfo *Info +); + +/** + Function for setting up PCI controller +**/ +VOID +PcieSetupCntrl ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN LsPcie *Pcie, + IN LsPcieInfo *Info +); + +/** + Internal Helper function for read and write memory space +**/ +EFI_STATUS +RootBridgeIoMemRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer +); + +/** + Internal Helper function for read and write PCI IO space +**/ +EFI_STATUS +RootBridgeIoIoRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer +); + +/** + Internal Helper function for read and write PCI configuration space +**/ +EFI_STATUS +RootBridgeIoPciRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer +); + +#endif diff --git a/Platform/NXP/Include/PciLib.h b/Platform/NXP/Include/PciLib.h new file mode 100644 index 0000000..873f0e7 --- /dev/null +++ b/Platform/NXP/Include/PciLib.h @@ -0,0 +1,414 @@ +/** PciLib.h + Pci Library containing Defines for Pci Controller configuration etc + + Copyright 2017 NXP + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __PCI_LIB_H__ +#define __PCI_LIB_H__ + +/* + In PCI, devices have 256 bytes of configuration address space, + of which the first 64 bytes are standardized as follows: + **/ +#define LS_PCI_VENDOR_ID 0x00 // 16 bits +#define LS_PCI_DEVICE_ID 0x02 // 16 bits +#define LS_PCI_COMMAND 0x04 // 16 bits +#define LS_PCI_COMMAND_IO 0x1 // Enable response in I/O space +#define LS_PCI_COMMAND_MEMORY 0x2 // Enable response in Memory space +#define LS_PCI_COMMAND_MASTER 0x4 // Enable bus mastering +#define LS_PCI_COMMAND_SPECIAL 0x8 // Enable response to special cycles +#define LS_PCI_COMMAND_INVALIDATE 0x10 // Use memory write and invalidate +#define LS_PCI_COMMAND_VGA_PALETTE 0x20 // Enable palette snooping +#define LS_PCI_COMMAND_PARITY 0x40 // Enable parity checking +#define LS_PCI_COMMAND_WAIT 0x80 // Enable address/data stepping +#define LS_PCI_COMMAND_SERR 0x100 // Enable SERR +#define LS_PCI_COMMAND_FAST_BACK 0x200 + +#define LS_PCI_STATUS 0x06 // 16 bits +#define LS_PCI_STATUS_CAP_LIST 0x10 // Support Capability List +#define LS_PCI_STATUS_66MHZ 0x20 +#define LS_PCI_STATUS_UDF 0x40 +#define LS_PCI_STATUS_FAST_BACK 0x80 +#define LS_PCI_STATUS_PARITY 0x100 +#define LS_PCI_STATUS_DEVSEL_MASK 0x600 +#define LS_PCI_STATUS_DEVSEL_FAST 0x000 +#define LS_PCI_STATUS_DEVSEL_MEDIUM 0x200 +#define LS_PCI_STATUS_DEVSEL_SLOW 0x400 +#define LS_PCI_STATUS_SIG_TARGET_ABORT 0x800 +#define LS_PCI_STATUS_REC_TARGET_ABORT 0x1000 +#define LS_PCI_STATUS_REC_MASTER_ABORT 0x2000 +#define LS_PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 +#define LS_PCI_STATUS_DETECTED_PARITY 0x8000 + +#define LS_PCI_CLASS_REVISION 0x08 +#define LS_PCI_REVISION_ID 0x08 // Revision ID +#define LS_PCI_CLASS_PROG 0x09 +#define LS_PCI_CLASS_DEVICE 0x0a // Device class +#define LS_PCI_CLASS_CODE 0x0b // Device class code +#define LS_PCI_CLASS_CODE_TOO_OLD 0x00 +#define LS_PCI_CLASS_CODE_STORAGE 0x01 +#define LS_PCI_CLASS_CODE_NETWORK 0x02 +#define LS_PCI_CLASS_CODE_DISPLAY 0x03 +#define LS_PCI_CLASS_CODE_MULTIMEDIA 0x04 +#define LS_PCI_CLASS_CODE_MEMORY 0x05 +#define LS_PCI_CLASS_CODE_BRIDGE 0x06 +#define LS_PCI_CLASS_CODE_COMM 0x07 +#define LS_PCI_CLASS_CODE_PERIPHERAL 0x08 +#define LS_PCI_CLASS_CODE_INPUT 0x09 +#define LS_PCI_CLASS_CODE_DOCKING 0x0A +#define LS_PCI_CLASS_CODE_PROCESSOR 0x0B +#define LS_PCI_CLASS_CODE_SERIAL 0x0C +#define LS_PCI_CLASS_CODE_WIRELESS 0x0D +#define LS_PCI_CLASS_CODE_I2O 0x0E +#define LS_PCI_CLASS_CODE_SATELLITE 0x0F +#define LS_PCI_CLASS_CODE_CRYPTO 0x10 +#define LS_PCI_CLASS_CODE_DATA 0x11 +// Base Class 0x12 - 0xFE is reserved +#define LS_PCI_CLASS_CODE_OTHER 0xFF + +#define LS_PCI_CLASS_SUB_CODE 0x0a // Device sub-class code +#define LS_PCI_CLASS_SUB_CODE_TOO_OLD_NOTVGA 0x00 +#define LS_PCI_CLASS_SUB_CODE_TOO_OLD_VGA 0x01 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_SCSI 0x00 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_IDE 0x01 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_FLOPPY 0x02 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_IPIBUS 0x03 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_RAID 0x04 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_ATA 0x05 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_SATA 0x06 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_SAS 0x07 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_ETHERNET 0x00 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_TOKENRING 0x01 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_FDDI 0x02 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_ATM 0x03 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_ISDN 0x04 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_WORLDFIP 0x05 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_PICMG 0x06 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_DISPLAY_VGA 0x00 +#define LS_PCI_CLASS_SUB_CODE_DISPLAY_XGA 0x01 +#define LS_PCI_CLASS_SUB_CODE_DISPLAY_3D 0x02 +#define LS_PCI_CLASS_SUB_CODE_DISPLAY_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_VIDEO 0x00 +#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_AUDIO 0x01 +#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_PHONE 0x02 +#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_MEMORY_RAM 0x00 +#define LS_PCI_CLASS_SUB_CODE_MEMORY_FLASH 0x01 +#define LS_PCI_CLASS_SUB_CODE_MEMORY_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_HOST 0x00 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_ISA 0x01 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_EISA 0x02 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_MCA 0x03 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_LS_PCI 0x04 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_PCMCIA 0x05 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_NUBUS 0x06 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_CARDBUS 0x07 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_RACEWAY 0x08 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_SEMI_LS_PCI 0x09 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_INFINIBAND 0x0A +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_COMM_SERIAL 0x00 +#define LS_PCI_CLASS_SUB_CODE_COMM_PARALLEL 0x01 +#define LS_PCI_CLASS_SUB_CODE_COMM_MULTIPORT 0x02 +#define LS_PCI_CLASS_SUB_CODE_COMM_MODEM 0x03 +#define LS_PCI_CLASS_SUB_CODE_COMM_GPIB 0x04 +#define LS_PCI_CLASS_SUB_CODE_COMM_SMARTCARD 0x05 +#define LS_PCI_CLASS_SUB_CODE_COMM_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_PIC 0x00 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_DMA 0x01 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_TIMER 0x02 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_RTC 0x03 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_HOTPLUG 0x04 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_SD 0x05 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_INPUT_KEYBOARD 0x00 +#define LS_PCI_CLASS_SUB_CODE_INPUT_DIGITIZER 0x01 +#define LS_PCI_CLASS_SUB_CODE_INPUT_MOUSE 0x02 +#define LS_PCI_CLASS_SUB_CODE_INPUT_SCANNER 0x03 +#define LS_PCI_CLASS_SUB_CODE_INPUT_GAMEPORT 0x04 +#define LS_PCI_CLASS_SUB_CODE_INPUT_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_DOCKING_GENERIC 0x00 +#define LS_PCI_CLASS_SUB_CODE_DOCKING_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_386 0x00 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_486 0x01 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_PENTIUM 0x02 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_ALPHA 0x10 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_POWERPC 0x20 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_MIPS 0x30 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_COPROC 0x40 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_1394 0x00 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_ACCESSBUS 0x01 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_SSA 0x02 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_USB 0x03 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_FIBRECHAN 0x04 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_SMBUS 0x05 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_INFINIBAND 0x06 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_IPMI 0x07 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_SERCOS 0x08 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_CANBUS 0x09 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_IRDA 0x00 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_IR 0x01 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_RF 0x10 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_BLUETOOTH 0x11 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_BROADBAND 0x12 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_80211A 0x20 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_80211B 0x21 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_I2O_V1_0 0x00 +#define LS_PCI_CLASS_SUB_CODE_SATELLITE_TV 0x01 +#define LS_PCI_CLASS_SUB_CODE_SATELLITE_AUDIO 0x02 +#define LS_PCI_CLASS_SUB_CODE_SATELLITE_VOICE 0x03 +#define LS_PCI_CLASS_SUB_CODE_SATELLITE_DATA 0x04 +#define LS_PCI_CLASS_SUB_CODE_CRYPTO_NETWORK 0x00 +#define LS_PCI_CLASS_SUB_CODE_CRYPTO_ENTERTAINMENT 0x10 +#define LS_PCI_CLASS_SUB_CODE_CRYPTO_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_DATA_DPIO 0x00 +#define LS_PCI_CLASS_SUB_CODE_DATA_PERFCNTR 0x01 +#define LS_PCI_CLASS_SUB_CODE_DATA_COMMSYNC 0x10 +#define LS_PCI_CLASS_SUB_CODE_DATA_MGMT 0x20 +#define LS_PCI_CLASS_SUB_CODE_DATA_OTHER 0x80 + +#define LS_PCI_CACHE_LINE_SIZE 0x0c // 8 bits +#define LS_PCI_LATENCY_TIMER 0x0d // 8 bits +#define LS_PCI_HEADER_TYPE 0x0e // 8 bits +#define LS_PCI_HEADER_TYPE_NORMAL 0 +#define LS_PCI_HEADER_TYPE_BRIDGE 1 +#define LS_PCI_HEADER_TYPE_CARDBUS 2 + +#define LS_PCI_BIST 0x0f // 8 bits +#define LS_PCI_BIST_CODE_MASK 0x0f // Return result +#define LS_PCI_BIST_START 0x40 +#define LS_PCI_BIST_CAPABLE 0x80 + +#define LS_PCI_BASE_ADDRESS_0 0x10 // 32 bits +#define LS_PCI_BASE_ADDRESS_1 0x14 +#define LS_PCI_BASE_ADDRESS_2 0x18 +#define LS_PCI_BASE_ADDRESS_3 0x1c // 32 bits +#define LS_PCI_BASE_ADDRESS_4 0x20 // 32 bits +#define LS_PCI_BASE_ADDRESS_5 0x24 // 32 bits +#define LS_PCI_BASE_ADDRESS_SPACE 0x01 +#define LS_PCI_BASE_ADDRESS_SPACE_IO 0x01 +#define LS_PCI_BASE_ADDRESS_SPACE_MEMORY 0x00 +#define LS_PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06 +#define LS_PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 // 32 bit address +#define LS_PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 // Below 1M [obsolete] +#define LS_PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 // 64 bit address +#define LS_PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 // prefetchable? +#define LS_PCI_BASE_ADDRESS_MEM_MASK (~0x0fULL) +#define LS_PCI_BASE_ADDRESS_IO_MASK (~0x03ULL) + +// Header type 0 (normal devices) +#define LS_PCI_CARDBUS_CIS 0x28 +#define LS_PCI_SUBSYSTEM_VENDOR_ID 0x2c +#define LS_PCI_SUBSYSTEM_ID 0x2e +#define LS_PCI_ROM_ADDRESS 0x30 +#define LS_PCI_ROM_ADDRESS_ENABLE 0x01 +#define LS_PCI_ROM_ADDRESS_MASK (~0x7ffULL) + +#define LS_PCI_CAPABILITY_LIST 0x34 // Offset of first capability list entry + +#define LS_PCI_INTERRUPT_LINE 0x3c // 8 bits +#define LS_PCI_INTERRUPT_PIN 0x3d // 8 bits +#define LS_PCI_MIN_GNT 0x3e // 8 bits +#define LS_PCI_MAX_LAT 0x3f // 8 bits + +// Header type 1 (PCI-to-PCI bridges) +#define LS_PCI_PRIMARY_BUS 0x18 // Primary bus number +#define LS_PCI_SECONDARY_BUS 0x19 // Secondary bus number +#define LS_PCI_SUBORDINATE_BUS 0x1a +#define LS_PCI_SEC_LATENCY_TIMER 0x1b +#define LS_PCI_IO_BASE 0x1c // I/O range behind the bridge +#define LS_PCI_IO_LIMIT 0x1d +#define LS_PCI_IO_RANGE_TYPE_MASK 0x0f // I/O bridging type +#define LS_PCI_IO_RANGE_TYPE_16 0x00 +#define LS_PCI_IO_RANGE_TYPE_32 0x01 +#define LS_PCI_IO_RANGE_MASK ~0x0f +#define LS_PCI_SEC_STATUS 0x1e +#define LS_PCI_MEMORY_BASE 0x20 // Memory range behind +#define LS_PCI_MEMORY_LIMIT 0x22 +#define LS_PCI_MEMORY_RANGE_TYPE_MASK 0x0f +#define LS_PCI_MEMORY_RANGE_MASK ~0x0f +#define LS_PCI_PREF_MEMORY_BASE 0x24 // Prefetchable memory range behind +#define LS_PCI_PREF_MEMORY_LIMIT 0x26 +#define LS_PCI_PREF_RANGE_TYPE_MASK 0x0f +#define LS_PCI_PREF_RANGE_TYPE_32 0x00 +#define LS_PCI_PREF_RANGE_TYPE_64 0x01 +#define LS_PCI_PREF_RANGE_MASK ~0x0f +#define LS_PCI_PREF_BASE_UPPER32 0x28 // Upper half of prefetchable memory range +#define LS_PCI_PREF_LIMIT_UPPER32 0x2c +#define LS_PCI_IO_BASE_UPPER16 0x30 // Upper half of I/O addresses +#define LS_PCI_IO_LIMIT_UPPER16 0x32 +#define LS_PCI_ROM_ADDRESS1 0x38 // Same as LS_PCI_ROM_ADDRESS, but for htype 1 +#define LS_PCI_BRIDGE_CONTROL 0x3e +#define LS_PCI_BRIDGE_CTL_PARITY 0x01 +#define LS_PCI_BRIDGE_CTL_SERR 0x02 +#define LS_PCI_BRIDGE_CTL_NO_ISA 0x04 +#define LS_PCI_BRIDGE_CTL_VGA 0x08 +#define LS_PCI_BRIDGE_CTL_MASTER_ABORT 0x20 // Report master aborts +#define LS_PCI_BRIDGE_CTL_BUS_RESET 0x40 // Secondary bus reset +#define LS_PCI_BRIDGE_CTL_FAST_BACK 0x80 + +#define LS_PCI_ERREN 0x48 // Error Enable +#define LS_PCI_ERRSTS 0x49 // Error Status +#define LS_PCI_BRDGOPT1 0x4A +#define LS_PCI_PLBSESR0 0x4C +#define LS_PCI_PLBSESR1 0x50 +#define LS_PCI_PLBSEAR 0x54 +#define LS_PCI_CAPID 0x58 +#define LS_PCI_NEXTITEMPTR 0x59 +#define LS_PCI_PMC 0x5A +#define LS_PCI_PMCSR 0x5C +#define LS_PCI_PMCSRBSE 0x5E +#define LS_PCI_BRDGOPT2 0x60 // PCI Bridge Options 2 +#define LS_PCI_PMSCRR 0x64 + +// Header type 2 (CardBus bridges) +#define LS_PCI_CB_CAPABILITY_LIST 0x14 +// 0x15 reserved +#define LS_PCI_CB_SEC_STATUS 0x16 // Secondary status +#define LS_PCI_CB_PRIMARY_BUS 0x18 // PCI bus number +#define LS_PCI_CB_CARD_BUS 0x19 +#define LS_PCI_CB_SUBORDINATE_BUS 0x1a // Subordinate bus number +#define LS_PCI_CB_LATENCY_TIMER 0x1b +#define LS_PCI_CB_MEMORY_BASE_0 0x1c +#define LS_PCI_CB_MEMORY_LIMIT_0 0x20 +#define LS_PCI_CB_MEMORY_BASE_1 0x24 +#define LS_PCI_CB_MEMORY_LIMIT_1 0x28 +#define LS_PCI_CB_IO_BASE_0 0x2c +#define LS_PCI_CB_IO_BASE_0_HI 0x2e +#define LS_PCI_CB_IO_LIMIT_0 0x30 +#define LS_PCI_CB_IO_LIMIT_0_HI 0x32 +#define LS_PCI_CB_IO_BASE_1 0x34 +#define LS_PCI_CB_IO_BASE_1_HI 0x36 +#define LS_PCI_CB_IO_LIMIT_1 0x38 +#define LS_PCI_CB_IO_LIMIT_1_HI 0x3a +#define LS_PCI_CB_IO_RANGE_MASK ~0x03 +#define LS_PCI_CB_BRIDGE_CONTROL 0x3e +#define LS_PCI_CB_BRIDGE_CTL_PARITY 0x01 // Similar to standard bridge control register +#define LS_PCI_CB_BRIDGE_CTL_SERR 0x02 +#define LS_PCI_CB_BRIDGE_CTL_ISA 0x04 +#define LS_PCI_CB_BRIDGE_CTL_VGA 0x08 +#define LS_PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20 +#define LS_PCI_CB_BRIDGE_CTL_CB_RESET 0x40 // CardBus reset +#define LS_PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 +#define LS_PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 // Prefetch enable for both memory regions +#define LS_PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200 +#define LS_PCI_CB_BRIDGE_CTL_POST_WRITES 0x400 +#define LS_PCI_CB_SUBSYSTEM_VENDOR_ID 0x40 +#define LS_PCI_CB_SUBSYSTEM_ID 0x42 +#define LS_PCI_CB_LEGACY_MODE_BASE 0x44 // 16-bit PC Card legacy mode base address (ExCa) + +// Defines of Capability lists +#define LS_PCI_CAP_LIST_ID 0 // Capability ID +#define LS_PCI_CAP_ID_PM 0x01 // Power Management +#define LS_PCI_CAP_ID_AGP 0x02 +#define LS_PCI_CAP_ID_VPD 0x03 +#define LS_PCI_CAP_ID_SLOTID 0x04 +#define LS_PCI_CAP_ID_MSI 0x05 +#define LS_PCI_CAP_ID_CHSWP 0x06 +#define LS_PCI_CAP_ID_EXP 0x10 +#define LS_PCI_CAP_LIST_NEXT 1 // Next capability in the list +#define LS_PCI_CAP_FLAGS 2 // Capability defined flags (16 bits) +#define LS_PCI_CAP_SIZEOF 4 + +// Power Management Registers +#define LS_PCI_PM_CAP_VER_MASK 0x0007 +#define LS_PCI_PM_CAP_PME_CLOCK 0x0008 +#define LS_PCI_PM_CAP_AUX_POWER 0x0010 +#define LS_PCI_PM_CAP_DSI 0x0020 +#define LS_PCI_PM_CAP_D1 0x0200 +#define LS_PCI_PM_CAP_D2 0x0400 +#define LS_PCI_PM_CAP_PME 0x0800 +#define LS_PCI_PM_CTRL 4 +#define LS_PCI_PM_CTRL_STATE_MASK 0x0003 +#define LS_PCI_PM_CTRL_PME_ENABLE 0x0100 +#define LS_PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 +#define LS_PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 +#define LS_PCI_PM_CTRL_PME_STATUS 0x8000 +#define LS_PCI_PM_PPB_EXTENSIONS 6 +#define LS_PCI_PM_PPB_B2_B3 0x40 +#define LS_PCI_PM_BPCC_ENABLE 0x80 +#define LS_PCI_PM_DATA_REGISTER 7 +#define LS_PCI_PM_SIZEOF 8 + +// AGP registers defines +#define LS_PCI_AGP_VERSION 2 +#define LS_PCI_AGP_RFU 3 +#define LS_PCI_AGP_STATUS 4 +#define LS_PCI_AGP_STATUS_RQ_MASK 0xff000000 +#define LS_PCI_AGP_STATUS_SBA 0x0200 +#define LS_PCI_AGP_STATUS_64BIT 0x0020 +#define LS_PCI_AGP_STATUS_FW 0x0010 +#define LS_PCI_AGP_STATUS_RATE4 0x0004 +#define LS_PCI_AGP_STATUS_RATE2 0x0002 +#define LS_PCI_AGP_STATUS_RATE1 0x0001 +#define LS_PCI_AGP_COMMAND 8 +#define LS_PCI_AGP_COMMAND_RQ_MASK 0xff000000 +#define LS_PCI_AGP_COMMAND_SBA 0x0200 +#define LS_PCI_AGP_COMMAND_AGP 0x0100 +#define LS_PCI_AGP_COMMAND_64BIT 0x0020 +#define LS_PCI_AGP_COMMAND_FW 0x0010 +#define LS_PCI_AGP_COMMAND_RATE4 0x0004 +#define LS_PCI_AGP_COMMAND_RATE2 0x0002 +#define LS_PCI_AGP_COMMAND_RATE1 0x0001 +#define LS_PCI_AGP_SIZEOF 12 + +// Defines for PCI-X registers +#define LS_PCI_X_CMD_DPERR_E 0x0001 +#define LS_PCI_X_CMD_ERO 0x0002 +#define LS_PCI_X_CMD_MAX_READ 0x0000 +#define LS_PCI_X_CMD_MAX_SPLIT 0x0030 +#define LS_PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) + +// Register of Slot Identification +#define LS_PCI_SID_ESR 2 // Expansion Slot Register +#define LS_PCI_SID_ESR_NSLOTS 0x1f // Number of expansion slots available +#define LS_PCI_SID_ESR_FIC 0x20 // First In Chassis Flag +#define LS_PCI_SID_CHASSIS_NR 3 // Chassis Number + +#define LS_PCI_MSI_FLAGS 2 +#define LS_PCI_MSI_FLAGS_64BIT 0x80 +#define LS_PCI_MSI_FLAGS_QSIZE 0x70 +#define LS_PCI_MSI_FLAGS_QMASK 0x0e +#define LS_PCI_MSI_FLAGS_ENABLE 0x01 +#define LS_PCI_MSI_RFU 3 +#define LS_PCI_MSI_ADDRESS_LO 4 +#define PCI_MSI_ADDRESS_HI 8 +#define LS_PCI_MSI_DATA_32 8 +#define LS_PCI_MSI_DATA_64 12 + +#define LS_PCI_MAX_PCI_DEVICES 32 +#define LS_PCI_MAX_PCI_FUNCTIONS 8 + +#define LS_PCI_FIND_CAP_TTL 0x48 +#define CAP_START_POS 0x40 + +#define LS_PCI_REGION_MEM 0x00000000 // PCI memory space +#define LS_PCI_REGION_IO 0x00000001 // PCI IO space +#define LS_PCI_REGION_TYPE 0x00000001 +#define LS_PCI_REGION_PREFETCH 0x00000008 // prefetchable PCI memory +#define LS_PCI_REGION_SYS_MEMORY 0x00000100 // System memory +#define LS_PCI_REGION_RO 0x00000200 // Read-only memory + +#define PCI_BUS(Dev) (((Dev) >> 16) & 0xff) +#define PCI_DEV(Dev) (((Dev) >> 11) & 0x1f) +#define PCI_FUNC(Dev) (((Dev) >> 8) & 0x7) +#define PCI_BDF(B,D,F) ((B) << 16 | (D) << 11 | (F) << 8) + +#define PCI_ANY_ID (~0) + +#define INDIRECT_TYPE_NO_PCIE_LINK 1 + +#endif /* _PCI_LIB_H */ diff --git a/Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c b/Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c new file mode 100644 index 0000000..942e04e --- /dev/null +++ b/Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c @@ -0,0 +1,628 @@ +/** PciCntrl.c + Provides the basic interfaces to be used by PCI Root Bridge IO protocol + + Copyright 2017 NXP + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +#include +#include "PciHostBridge.h" + +PCI_ROOT_BRIDGE_INSTANCE *RootBridgeHead; + +/** + Function for setting up PCI region +**/ +VOID +PciSetRegion ( + IN PciRegion *Reg, + IN PciAddrT BusStart, + IN PhysAddrT PhysStart, + IN PciSizeT Size, + IN UINTN Flags +) +{ + Reg->BusStart = BusStart; + Reg->PhysStart = PhysStart; + Reg->Size = Size; + Reg->Flags = Flags; +} + +/** + Function to set PCI Space + - Configuration space + - Memory Space + - I/O Space +**/ +VOID +SetLSPcieInfo ( + IN LsPcieInfo *PcieInfo, + IN UINTN Num +) +{ + UINTN pciePhyAddr, pcieSysaddr; + + pciePhyAddr=0; + pcieSysaddr=0; + + switch(Num){ + case 1: + pciePhyAddr = PcdGet64 (PcdPciExp1BaseAddr); + pcieSysaddr = PcdGet64 (PcdPciExp1SysAddr); + break; + case 2: + pciePhyAddr = PcdGet64 (PcdPciExp2BaseAddr); + pcieSysaddr = PcdGet64 (PcdPciExp2SysAddr); + break; + case 3: + pciePhyAddr = PcdGet64 (PcdPciExp3BaseAddr); + pcieSysaddr = PcdGet64 (PcdPciExp3SysAddr); + break; + case 4: + pciePhyAddr = PcdGet64 (PcdPciExp4BaseAddr); + pcieSysaddr = PcdGet64 (PcdPciExp4SysAddr); + break; + } + + PcieInfo->Regs = pcieSysaddr; + PcieInfo->Cfg0Phys = LS_PCIE_CFG0_PHYS_OFF + pciePhyAddr; + PcieInfo->Cfg0Size = LS_PCIE_CFG0_SIZE; + PcieInfo->Cfg1Phys = LS_PCIE_CFG1_PHYS_OFF + pciePhyAddr; + PcieInfo->Cfg1Size = LS_PCIE_CFG1_SIZE; + PcieInfo->MemBus = LS_PCIE_MEM_BUS; + PcieInfo->MemPhys = LS_PCIE_MEM_PHYS_OFF + pciePhyAddr; + PcieInfo->MemSize = LS_PCIE_MEM_SIZE; + PcieInfo->IoBus = LS_PCIE_IO_BUS; + PcieInfo->IoPhys = LS_PCIE_IO_PHYS_OFF + pciePhyAddr; + PcieInfo->IoSize = LS_PCIE_IO_SIZE; + PcieInfo->PciNum = Num; + + if (FeaturePcdGet (PcdPciDebug) == TRUE) { + DEBUG ((DEBUG_INFO, "In SET_PCIE_INFO: %d\n", Num)); + DEBUG ((DEBUG_INFO, "PciNum:%d Info CFG Values: %016llx %016llx:%016llx %016llx %016llx\n", + (UINT64)PcieInfo->PciNum, + (UINT64)PcieInfo->Regs, + (UINT64)PcieInfo->Cfg0Phys, + (UINT64)PcieInfo->Cfg0Size, + (UINT64)PcieInfo->Cfg1Phys, + (UINT64)PcieInfo->Cfg1Size)); + DEBUG ((DEBUG_INFO, "Info Mem Values: %016llx:%016llx %016llx\n", + (UINT64)PcieInfo->MemBus, + (UINT64)PcieInfo->MemPhys, + (UINT64)PcieInfo->MemSize)); + DEBUG ((DEBUG_INFO, "Info IO Values: %016llx:%016llx %016llx\n", + (UINT64)PcieInfo->IoBus, + (UINT64)PcieInfo->IoPhys, + (UINT64)PcieInfo->IoSize)); + } +} + +/** + Function to check PCIe link state +**/ +INTN +PcieLinkState ( + IN LsPcie *Pcie +) +{ + UINT32 State; + if (FeaturePcdGet (PcdPciLutBigEndian)) { + State = BeMmioRead32 ((UINTN)(Pcie->Dbi) + LS_PCIE_LUT_BASE + LS_PCIE_LUT_DBG) & + LS_LTSSM_STATE_MASK; + } + else { + State = MmioRead32 ((UINTN)(Pcie->Dbi) + LS_PCIE_LUT_BASE + LS_PCIE_LUT_DBG) & + LS_LTSSM_STATE_MASK; + } + + if (State < LS_LTSSM_PCIE_L0) { + DEBUG ((DEBUG_INFO," Pcie Link error. LTSSM=0x%2x\n", + State)); + return EFI_SUCCESS; + } + + return EFI_UNSUPPORTED; +} + +/** + Helper function to check PCIe link is up + Download the speed to gen1 +**/ +INTN +PcieLinkUp ( + IN LsPcie *Pcie +) +{ + INTN State; + UINT32 Cap; + + State = PcieLinkState (Pcie); + if (State) { + return State; + } + + // Try to download speed to gen1 + Cap = MmioRead32 ((UINTN)(Pcie->Dbi) + LS_PCIE_LINK_CAP); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_LINK_CAP, (UINT32)(Cap & (~LS_PCIE_LINK_SPEED_MASK)) | 1); + State = PcieLinkState (Pcie); + if (State) { + return State; + } + + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_LINK_CAP, Cap); + + return EFI_SUCCESS; +} + +/** + Function to set up PCI configuration(cfg0) space +**/ +VOID +PcieCfg0SetBusdev ( + IN LsPcie *Pcie, + IN UINT32 BusDev +) +{ + MmioWrite32 ((UINTN)(Pcie->Dbi + LS_PCIE_ATU_VIEWPORT), + LS_PCIE_ATU_REGION_OUTBOUND | LS_PCIE_ATU_REGION_INDEX0); + MmioWrite32 ((UINTN)(Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET), BusDev); +} + +/** + Function to set up PCI configuration(cfg1) space +**/ +VOID +PcieCfg1SetBusdev ( + IN LsPcie *Pcie, + IN UINT32 BusDev +) +{ + MmioWrite32 ((UINTN)(Pcie->Dbi + LS_PCIE_ATU_VIEWPORT), + LS_PCIE_ATU_REGION_OUTBOUND | LS_PCIE_ATU_REGION_INDEX1); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET, BusDev); +} + +/** + Function to set up internal address translation window for inbound + transaction +**/ +VOID +PcieIatuInboundSet ( + IN LsPcie *Pcie, + IN UINT32 Idx, + IN UINT32 Bar, + IN UINT64 Phys +) +{ + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT, (UINT32)(LS_PCIE_ATU_REGION_INBOUND | Idx)); + + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_BASE, Phys); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_BASE, (UINT32)(Phys >> 32)); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET, (UINT32)Phys); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_TARGET, (UINT32)(Phys >> 32)); + + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR1, LS_PCIE_ATU_TYPE_MEM); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR2, LS_PCIE_ATU_ENABLE); +} + +/** + Function to set up internal address translation window for outbound + transaction +**/ +VOID +PcieIatuOutboundSet ( + IN LsPcie *Pcie, + IN UINT32 Idx, + IN UINT32 Type, + IN UINT64 Phys, + IN UINT64 BusAddr, + IN UINT64 Size +) +{ + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT, (UINT32)(LS_PCIE_ATU_REGION_OUTBOUND | Idx)); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_BASE, Phys); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_BASE, (UINT32)(Phys >> 32)); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LIMIT, (UINT32)(Phys + Size -1)); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET, (UINT32)BusAddr); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_TARGET, (UINT32)(BusAddr >> 32)); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR1, (UINT32)Type); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR2, LS_PCIE_ATU_ENABLE); +} + +EFI_STATUS +PciSkipDev ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev +) +{ + // Do not skip controller + return EFI_SUCCESS; +} + +/** + Function to check whether PCIe address is valid +**/ +EFI_STATUS +PcieAddrValid ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev +) +{ + if ((((Dev >> 19)) & 0x1f) > 0) { + return EFI_DEVICE_ERROR; + } + + // No support for multi-function + if ((((Dev >> 16)) & 0x07) > 0) { + return EFI_DEVICE_ERROR; + } + + // Controller does not support multi-function in RC mode + if (((((Dev) >> 24) & 0xff) == PrivateData->FirstBusno) && ((((Dev) >> 16) & 0x7) > 0)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Function to read from PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return The value(32-bit) read + +**/ + +EFI_STATUS +PcieReadConfig ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Where, + IN OUT UINT32 *Val +) +{ + LsPcie *Pcie; + UINT32 BusDev, *Addr; + + *Val = 0x00000000; + Pcie = PrivateData->Pcie; + + if (PcieAddrValid (PrivateData, Dev)) { + *Val = 0xffffffff; + return EFI_DEVICE_ERROR; + } + + if ((((Dev) >> 24) & 0xff) == PrivateData->FirstBusno) { + Addr = Pcie->Dbi + Where; + } else { + BusDev = Dev; + + if ((((Dev) >> 24) & 0xff) == PrivateData->FirstBusno + 1) { + PcieCfg0SetBusdev (Pcie, BusDev); + Addr = (VOID *)Pcie->VaCfg0 + Where; + } else { + PcieCfg1SetBusdev (Pcie, BusDev); + Addr = (VOID *)Pcie->VaCfg1 + Where; + } + } + + *Val = MmioRead32 ((UINTN)Addr); + return EFI_SUCCESS; +} + +/** + Function to read byte from PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return The value(8-bit) read + +**/ + +EFI_STATUS +PcieReadConfigByte ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + IN OUT UINT8 *Val +) +{ + UINT32 Val32; + + if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))) { + *Val = -1; + return EFI_DEVICE_ERROR; + } + + *Val = (Val32 >> ((Offset & (INT32)0x03) * 8)); + + return EFI_SUCCESS; +} + +/** + Function to read word(16-bit) from PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return The value(16-bit) read + +**/ + +EFI_STATUS +PcieReadConfigWord ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + IN OUT UINT16 *Val +) +{ + UINT32 Val32; + + if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))) { + *Val = -1; + return EFI_DEVICE_ERROR; + } + + *Val = (UINT16)(Val32 >> ((Offset & (INT32)0x02) * 8)); + + return EFI_SUCCESS; +} + +/** + Function to write byte to PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return EFI_SUCCESS (8-bit value written) + +**/ + +EFI_STATUS +PcieWriteConfigByte ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + OUT UINT8 Val +) +{ + UINT32 Val32, Mask, Ldata, Shift; + + if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))) { + return EFI_DEVICE_ERROR; + } + + Shift = ((Offset & (INT32)0x03) * 8); + Ldata = (((UINT32)Val) & 0x000000ff) << Shift; + Mask = 0x000000ff << Shift; + Val32 = (Val32 & ~Mask) | Ldata; + + if (EFI_ERROR (PcieWriteConfig (PrivateData, Dev, Offset & 0xfc, Val32))) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Function to write word to PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return EFI_SUCCESS (16-bit value written) + +**/ + +EFI_STATUS +PcieWriteConfigWord ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + OUT UINT16 Val +) +{ + UINT32 Val32, Mask, Ldata, Shift; + + if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))) { + return EFI_DEVICE_ERROR; + } + + Shift = ((Offset & (INT32)0x02) * 8); + Ldata = (((UINT32)Val) & 0x0000ffff) << Shift; + Mask = 0x0000ffff << Shift; + Val32 = (Val32 & ~Mask) | Ldata; + + if (EFI_ERROR (PcieWriteConfig (PrivateData, Dev, Offset & 0xfc, Val32))) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Function to write to PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return EFI_SUCCESS (32-bit value written) + +**/ + +EFI_STATUS +PcieWriteConfig ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Where, + IN UINT32 Val +) +{ + LsPcie *Pcie; + UINT32 BusDev, *Addr; + + Pcie = PrivateData->Pcie; + + if (PcieAddrValid (PrivateData, Dev)) { + return EFI_DEVICE_ERROR; + } + + if ((((Dev) >> 24) & 0xff) == PrivateData->FirstBusno) { + Addr = Pcie->Dbi + (Where & ~0x3); + } else { + BusDev = Dev; + + if ((((Dev) >> 24) & 0xff) == PrivateData->FirstBusno + 1) { + PcieCfg0SetBusdev (Pcie, BusDev); + Addr = (VOID *)Pcie->VaCfg0 + (Where & ~0x3); + } else { + PcieCfg1SetBusdev (Pcie, BusDev); + Addr = (VOID *)Pcie->VaCfg1 + (Where & ~0x3); + } + } + + MmioWrite32 ((UINTN)Addr, (UINT32)Val); + return EFI_SUCCESS; +} + +/** + Function to set up address translation unit for PCI + inbound transactions +**/ +VOID +PcieSetupAtuInbound ( + IN LsPcie *Pcie, + IN LsPcieInfo *Info +) +{ + UINT32 ValIn; + UINT32 ValOut; + UINT32 *Addr; + + ValIn = 0x00000000; + ValOut = 0x28282828; + Addr = (UINT32 *)0x80080000; + + MmioWrite32 ((UINTN)Addr, (UINT32)ValOut); + DEBUG ((DEBUG_INFO,"\nValue: %08lx written on Addr: %08lx\n", ValOut, Addr)); + ValIn = MmioRead32 ((UINTN)Addr); + DEBUG ((DEBUG_INFO, "Value Read: %08lx from Address: %llx\n", ValIn, Addr)); + // ATU 2 : OUTBOUND : MEM + PcieIatuInboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX2, 1, 0x80080000); + + Addr = (VOID *)Pcie->VaCfg0 + 0x40000000; + ValIn = MmioRead32 ((UINTN)Addr); + DEBUG ((DEBUG_INFO, "Inbound: Value Read: %08lx from Address: %llx\n", ValIn, Addr)); + Addr = (VOID *)Pcie->VaCfg0 + 0x00000000; + ValIn = MmioRead32 ((UINTN)Addr); + DEBUG ((DEBUG_INFO, "Inbound: Value Read: %08lx from Address: %llx\n", ValIn, Addr)); + Addr = (UINT32 *)0x80080000; + ValIn = MmioRead32((UINTN)Addr); + DEBUG ((DEBUG_INFO, "Inbound: Value Read: %08lx from Address: %llx\n", ValIn, Addr)); + +} + +/** + Function to set up address translation unit for PCI + outbound transactions +**/ +VOID +PcieSetupAtu ( + IN LsPcie *Pcie, + IN LsPcieInfo *Info +) +{ + // ATU 0 : OUTBOUND : CFG0 + PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX0, + LS_PCIE_ATU_TYPE_CFG0, + Info->Cfg0Phys, + 0, + Info->Cfg0Size); + + // ATU 1 : OUTBOUND : CFG1 + PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX1, + LS_PCIE_ATU_TYPE_CFG1, + Info->Cfg1Phys, + 0, + Info->Cfg1Size); + + // ATU 2 : OUTBOUND : MEM + PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX2, + LS_PCIE_ATU_TYPE_MEM, + Info->MemPhys, + Info->MemBus, + //0x10000000, + Info->MemSize); + + // ATU 3 : OUTBOUND : IO + PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX3, + LS_PCIE_ATU_TYPE_IO, + Info->IoPhys, + Info->IoBus, + Info->IoSize); + + if (FeaturePcdGet (PcdPciDebug) == TRUE) { + INTN Cnt; + UINTN AddrTemp; + for (Cnt = 0; Cnt <= LS_PCIE_ATU_REGION_INDEX3; Cnt++) { + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT, + (UINT32)(LS_PCIE_ATU_REGION_OUTBOUND | Cnt)); + DEBUG ((DEBUG_INFO,"iATU%d:\n", Cnt)); + AddrTemp = (UINTN)((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT); + DEBUG((DEBUG_INFO,"iATU%d VIEWPORT REG Addr:%08lx Val:%08lx\n", + Cnt, AddrTemp, MmioRead32(AddrTemp))); + DEBUG ((DEBUG_INFO,"iATU%d VIEWPORT REG:%08lx\n", Cnt, + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT))); + DEBUG ((DEBUG_INFO,"\tLOWER PHYS 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_BASE))); + DEBUG ((DEBUG_INFO,"\tUPPER PHYS 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_BASE))); + DEBUG ((DEBUG_INFO,"\tLOWER BUS 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET))); + DEBUG ((DEBUG_INFO,"\tUPPER BUS 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_TARGET))); + DEBUG ((DEBUG_INFO,"\tLIMIT 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LIMIT))); + DEBUG ((DEBUG_INFO,"\tCR1 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR1))); + DEBUG ((DEBUG_INFO,"\tCR2 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR2))); + } + } +} + +/** + Function to set up PCI controller + -Setup ATU + -Setup Root complex class +**/ +VOID +PcieSetupCntrl ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN LsPcie *Pcie, + IN LsPcieInfo *Info +) +{ + UINTN Dev; + + Dev = ((PrivateData->FirstBusno) << 16 | (0) << 11 | (0) << 8); + + if (FeaturePcdGet (PcdPciDebug) == TRUE) { + DEBUG ((DEBUG_INFO, "Going to SetUp IATU\n\n")); + } + + PcieSetupAtu (Pcie, Info); + + PcieWriteConfig (PrivateData, Dev, LS_PCI_BASE_ADDRESS_0, 0); + + // program correct class for RC + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_DBI_RO_WR_EN, (UINT32)1); + PcieWriteConfigWord (PrivateData, Dev, LS_PCI_CLASS_DEVICE, + PCI_CLASS_BRIDGE_PCI); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_DBI_RO_WR_EN, (UINT32)0); +} diff --git a/Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf new file mode 100644 index 0000000..f281357 --- /dev/null +++ b/Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -0,0 +1,49 @@ +/* PciHostBridgeLib.inf +# +# Component description file for PCI root Bridge Library +# +# Copyright 2017 NXP +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +*/ + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = PciHostBridgeLib + FILE_GUID = c0f5dfa0-7599-11e0-9865-0002a5d5c61b + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PciHostBridgeLib + +[Packages] + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec + Platform/NXP/NxpQoriqLs.dec + Silicon/NXP/Chassis/Chassis2/Chassis2.dec + +[Sources.common] + PciCntrl.c + PciRbLib.c + +[FixedPcd] + gNxpQoriqLsTokenSpaceGuid.PcdPciDebug + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp2BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp3BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp4BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1SysAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp2SysAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp3SysAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp4SysAddr + gArmTokenSpaceGuid.PcdSystemMemoryBase + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg + gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian diff --git a/Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c b/Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c new file mode 100644 index 0000000..4ebfc73 --- /dev/null +++ b/Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c @@ -0,0 +1,331 @@ +/** PciRbLib.c + Functions supporting PCI Root Bridge Io Protocol + + Some part of code is inspired from EDK II, file: + PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c + + Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved. + Copyright 2017 NXP + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PciHostBridge.h" + +// +// Lookup table for increment values based on transfer widths +// +UINT8 mInStride[] = { + 1, // EfiPciWidthUint8 + 2, // EfiPciWidthUint16 + 4, // EfiPciWidthUint32 + 8, // EfiPciWidthUint64 + 0, // EfiPciWidthFifoUint8 + 0, // EfiPciWidthFifoUint16 + 0, // EfiPciWidthFifoUint32 + 0, // EfiPciWidthFifoUint64 + 1, // EfiPciWidthFillUint8 + 2, // EfiPciWidthFillUint16 + 4, // EfiPciWidthFillUint32 + 8 // EfiPciWidthFillUint64 +}; + +// +// Lookup table for increment values based on transfer widths +// +UINT8 mOutStride[] = { + 1, // EfiPciWidthUint8 + 2, // EfiPciWidthUint16 + 4, // EfiPciWidthUint32 + 8, // EfiPciWidthUint64 + 1, // EfiPciWidthFifoUint8 + 2, // EfiPciWidthFifoUint16 + 4, // EfiPciWidthFifoUint32 + 8, // EfiPciWidthFifoUint64 + 0, // EfiPciWidthFillUint8 + 0, // EfiPciWidthFillUint16 + 0, // EfiPciWidthFillUint32 + 0 // EfiPciWidthFillUint64 +}; + +/** + Function to validate parameters(Operation type,Supported width) for + root bridge io operation + + @param This Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL + + @param OperationType Operation type(Mem,I/O,Config) + + @param Width Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH + + @return EFI_SUCCESS Paramters check is ok for operation + + @return EFI_INVALID_PARAMETER Inavlide parameters + +**/ +STATIC EFI_STATUS +RootBridgeIoCheckParameter ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN OPERATION_TYPE OperationType, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ) +{ + if ((Width >= EfiPciWidthMaximum) || (Width < EfiPciWidthUint8) || (NULL == Buffer)) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** + Internal help function for read and write memory space. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Write Switch value for Read or Write. + @param[in] Width Signifies the width of the memory operations. + @param[in] UserAddress The address within the PCI configuration space for the PCI controller. + @param[in] Count The number of PCI configuration operations to perform. Bytes + moved is Width size * Count, starting at Address. + @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +EFI_STATUS +RootBridgeIoMemRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 InStride; + UINT8 OutStride; + UINT8 *Uint8Buffer; + PCI_ROOT_BRIDGE_INSTANCE *PrivateData; + + Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + + if ((Address < LS_PCIE_MEM_PHYS_OFF) || + (Address >= ((UINT32)LS_PCIE_MEM_PHYS_OFF + + LS_PCIE_MEM_SIZE))) { + return EFI_INVALID_PARAMETER; + } + + PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This); + if (PrivateData == NULL ) { + return EFI_INVALID_PARAMETER; + } + + Address += PrivateData->PciBaseAddress64; + + InStride = mInStride[Width]; + OutStride = mOutStride[Width]; + + for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { + if (Write) { + switch (Width) { + case EfiPciWidthUint8: + MmioWrite8 ((UINTN)Address, *Uint8Buffer); + break; + case EfiPciWidthUint16: + MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer)); + break; + case EfiPciWidthUint32: + MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); + break; + case EfiPciWidthUint64: + MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer)); + break; + default: + // + // The RootBridgeIoCheckParameter call above will ensure that this + // path is not taken. + // + ASSERT (FALSE); + break; + } + } else { + switch (Width) { + case EfiPciWidthUint8: + *Uint8Buffer = MmioRead8 ((UINTN)Address); + break; + case EfiPciWidthUint16: + *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address); + break; + case EfiPciWidthUint32: + *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address); + break; + case EfiPciWidthUint64: + *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address); + break; + default: + // + // The RootBridgeIoCheckParameter call above will ensure that this + // path is not taken. + // + ASSERT (FALSE); + break; + } + } + } + return EFI_SUCCESS; +} + +/** + Internal help function for read and write IO space. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Write Switch value for Read or Write. + @param[in] Width Signifies the width of the memory operations. + @param[in] UserAddress The address within the PCI configuration space for the PCI controller. + @param[in] Count The number of PCI configuration operations to perform. Bytes + moved is Width size * Count, starting at Address. + @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +EFI_STATUS +RootBridgeIoIoRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + DEBUG ((DEBUG_INFO, "PCI Root Bridge Io Io Read/Write function is not implemented yet.\n")); + return EFI_SUCCESS; +} + +/** + Internal help function for read and write PCI configuration space. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Write Switch value for Read or Write. + @param[in] Width Signifies the width of the memory operations. + @param[in] UserAddress The address within the PCI configuration space for the PCI controller. + @param[in] Count The number of PCI configuration operations to perform. Bytes + moved is Width size * Count, starting at Address. + @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For + write operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +EFI_STATUS +RootBridgeIoPciRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + INT32 Offset; + UINT32 BusDev; + UINT8 InStride; + UINT8 OutStride; + UINT8 *Uint8Buffer; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr; + PCI_ROOT_BRIDGE_INSTANCE *PrivateData; + + PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This); + Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + + PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address; + + if (PciRbAddr->ExtendedRegister) { + Offset = (INT32) PciRbAddr->ExtendedRegister; + } + else { + Offset = (INT32) PciRbAddr->Register; + } + + BusDev = (UINT32)PCI_BUS_DEV ( + PciRbAddr->Bus, + PciRbAddr->Device, + PciRbAddr->Function + ); + + InStride = mInStride[Width]; + OutStride = mOutStride[Width]; + + for (Uint8Buffer = Buffer; Count > 0; Offset += InStride, Uint8Buffer += OutStride, Count--) { + if (Write) { + switch (Width) { + case EfiPciWidthUint8: + Status = PcieWriteConfigByte (PrivateData, (UINT32)BusDev, Offset, *Uint8Buffer); + break; + case EfiPciWidthUint16: + Status = PcieWriteConfigWord (PrivateData, (UINT32)BusDev, Offset, *(UINT16 *)Uint8Buffer); + break; + case EfiPciWidthUint32: + Status = PcieWriteConfig (PrivateData, (UINT32)BusDev, Offset, *(UINT32 *)Uint8Buffer); + break; + default: + // + // The RootBridgeIoCheckParameter call above will ensure that this + // path is not taken. + // + ASSERT (FALSE); + break; + } + } else { + switch (Width) { + case EfiPciWidthUint8: + Status = PcieReadConfigByte (PrivateData, (UINT32)BusDev, Offset, Uint8Buffer); + break; + case EfiPciWidthUint16: + Status = PcieReadConfigWord (PrivateData, (UINT32)BusDev, Offset, (UINT16 *)Uint8Buffer); + break; + case EfiPciWidthUint32: + Status = PcieReadConfig (PrivateData, (UINT32)BusDev, Offset, (UINT32 *)Uint8Buffer); + break; + default: + // + // The RootBridgeIoCheckParameter call above will ensure that this + // path is not taken. + // + ASSERT (FALSE); + break; + } + } + } + + return Status; +} -- 1.9.1