]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/XPressRich3.c
ArmPlatformPkg/ArmJuno: fix Juno PIO host bridge mapping
[mirror_edk2.git] / ArmPlatformPkg / ArmJunoPkg / Drivers / PciHostBridgeDxe / XPressRich3.c
CommitLineData
4595449b
OM
1/** @file\r
2* Initialize the XPress-RICH3 PCIe Root complex\r
3*\r
4* Copyright (c) 2011-2015, ARM Ltd. All rights reserved.\r
5*\r
6* This program and the accompanying materials\r
7* are licensed and made available under the terms and conditions of the BSD License\r
8* which accompanies this distribution. The full text of the license may be found at\r
9* http://opensource.org/licenses/bsd-license.php\r
10*\r
11* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13*\r
14**/\r
15\r
16#include "PciHostBridge.h"\r
17\r
18#include <Protocol/Cpu.h>\r
19\r
20#include "ArmPlatform.h"\r
21\r
22EFI_CPU_ARCH_PROTOCOL *mCpu;\r
23\r
24#define PCI_BRIDGE_REVISION_ID 1\r
25#define CLASS_CODE_REGISTER(Class, SubClass, ProgIf) ((Class << 16) | (SubClass << 8) | ProgIf)\r
26#define PLDA_BRIDGE_CCR CLASS_CODE_REGISTER(PCI_CLASS_BRIDGE, \\r
27 PCI_CLASS_BRIDGE_P2P, \\r
28 PCI_IF_BRIDGE_P2P)\r
29\r
30STATIC\r
31VOID\r
32SetTranslationAddressEntry (\r
33 IN EFI_CPU_IO2_PROTOCOL *CpuIo,\r
34 IN UINTN Entry,\r
35 IN UINT64 SourceAddress,\r
36 IN UINT64 TranslatedAddress,\r
37 IN UINT64 TranslationSize,\r
38 IN UINT64 TranslationParameter\r
39 )\r
40{\r
41 UINTN Log2Size = HighBitSet64 (TranslationSize);\r
42\r
43 // Ensure the size is a power of two. Restriction form the AXI Translation logic\r
44 // Othwerwise we increase the translation size\r
45 if (TranslationSize != (1ULL << Log2Size)) {\r
46 DEBUG ((EFI_D_WARN, "PCI: The size 0x%lX of the region 0x%lx has been increased to "\r
47 "be a power of two for the AXI translation table.\n",\r
48 TranslationSize, SourceAddress));\r
49 Log2Size++;\r
50 }\r
51\r
52 PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_SRC_ADDR_LOW_SIZE,\r
53 (UINT32)SourceAddress | ((Log2Size - 1) << 1) | 0x1);\r
54 PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_SRC_ADDR_HI, SourceAddress >> 32);\r
55\r
56 PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_TRSL_ADDR_LOW, (UINT32)TranslatedAddress);\r
57 PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_TRSL_ADDR_HI, TranslatedAddress >> 32);\r
58\r
59 PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_TRSL_PARAM, TranslationParameter);\r
60}\r
61\r
62EFI_STATUS\r
63HWPciRbInit (\r
64 IN EFI_CPU_IO2_PROTOCOL *CpuIo\r
65 )\r
66{\r
67 UINT32 Value;\r
68 UINT32 Index;\r
69 UINTN TranslationTable;\r
70\r
71 PCI_TRACE ("VExpressPciRbInit()");\r
72\r
73 PCI_TRACE ("PCIe Setting up Address Translation");\r
74\r
162e7891
JL
75 // The Juno PIO window is 8M, so we need full 32-bit PIO decoding.\r
76 PCIE_ROOTPORT_WRITE32 (PCIE_BAR_WIN, PCIE_BAR_WIN_SUPPORT_IO | PCIE_BAR_WIN_SUPPORT_IO32 |\r
77 PCIE_BAR_WIN_SUPPORT_MEM | PCIE_BAR_WIN_SUPPORT_MEM64);\r
4595449b
OM
78\r
79 // Setup the PCI Configuration Registers\r
80 // Offset 0a: SubClass 04 PCI-PCI Bridge\r
81 // Offset 0b: BaseClass 06 Bridge Device\r
82 // The Class Code register is a 24 bit and can be configured by setting up the PCIE_PCI_IDS\r
83 // Refer [1] Chapter 13\r
84 PCIE_ROOTPORT_WRITE32 (PCIE_PCI_IDS + PCIE_PCI_IDS_CLASSCODE_OFFSET, ((PLDA_BRIDGE_CCR << 8) | PCI_BRIDGE_REVISION_ID));\r
85\r
86 //\r
87 // PCIE Window 0 -> AXI4 Slave 0 Address Translations\r
88 //\r
89 TranslationTable = VEXPRESS_ATR_PCIE_WIN0;\r
90\r
91 // MSI Support\r
92 SetTranslationAddressEntry (CpuIo, TranslationTable, ARM_JUNO_GIV2M_MSI_BASE, ARM_JUNO_GIV2M_MSI_BASE,\r
93 ARM_JUNO_GIV2M_MSI_SZ, PCI_ATR_TRSLID_AXIDEVICE);\r
94 TranslationTable += PCI_ATR_ENTRY_SIZE;\r
95\r
96 // System Memory Support\r
97 SetTranslationAddressEntry (CpuIo, TranslationTable, PcdGet64 (PcdSystemMemoryBase), PcdGet64 (PcdSystemMemoryBase),\r
98 PcdGet64 (PcdSystemMemorySize), PCI_ATR_TRSLID_AXIMEMORY);\r
99 TranslationTable += PCI_ATR_ENTRY_SIZE;\r
100 SetTranslationAddressEntry (CpuIo, TranslationTable, ARM_JUNO_EXTRA_SYSTEM_MEMORY_BASE, ARM_JUNO_EXTRA_SYSTEM_MEMORY_BASE,\r
101 ARM_JUNO_EXTRA_SYSTEM_MEMORY_SZ, PCI_ATR_TRSLID_AXIMEMORY);\r
102\r
103 //\r
104 // PCIE Window 0 -> AXI4 Slave 0 Address Translations\r
105 //\r
106 TranslationTable = VEXPRESS_ATR_AXI4_SLV1;\r
107\r
108 // PCI ECAM Support\r
109 SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_ECAM_BASE, PCI_ECAM_BASE, PCI_ECAM_SIZE, PCI_ATR_TRSLID_PCIE_CONF);\r
110 TranslationTable += PCI_ATR_ENTRY_SIZE;\r
111\r
162e7891
JL
112 // PCI IO Support, the PIO space is translated from the arm MMIO PCI_IO_BASE address to the PIO base address of 0\r
113 // AKA, PIO addresses used by endpoints are generally in the range of 0-64K.\r
114 SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_IO_BASE, 0, PCI_IO_SIZE, PCI_ATR_TRSLID_PCIE_IO);\r
4595449b
OM
115 TranslationTable += PCI_ATR_ENTRY_SIZE;\r
116\r
117 // PCI MEM32 Support\r
118 SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_MEM32_BASE, PCI_MEM32_BASE, PCI_MEM32_SIZE, PCI_ATR_TRSLID_PCIE_MEMORY);\r
119 TranslationTable += PCI_ATR_ENTRY_SIZE;\r
120\r
121 // PCI MEM64 Support\r
122 SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_MEM64_BASE, PCI_MEM64_BASE, PCI_MEM64_SIZE, PCI_ATR_TRSLID_PCIE_MEMORY);\r
123\r
124 // Add credits\r
125 PCIE_ROOTPORT_WRITE32 (PCIE_VC_CRED, 0x00f0b818);\r
126 PCIE_ROOTPORT_WRITE32 (PCIE_VC_CRED + 4, 0x1);\r
127\r
128 // Allow ECRC\r
129 PCIE_ROOTPORT_WRITE32 (PCIE_PEX_SPC2, 0x6006);\r
130\r
131 // Reset controller\r
132 PCIE_CONTROL_WRITE32 (PCIE_CONTROL_RST_CTL, PCIE_CONTROL_RST_CTL_RCPHY_REL);\r
133\r
134 // Wait for reset\r
135 for (Index = 0; Index < 1000; Index++) {\r
136 gBS->Stall (1000);\r
137 PCIE_CONTROL_READ32 (PCIE_CONTROL_RST_STS, Value);\r
138 if ((Value & PCIE_CONTROL_RST_STS_RCPHYPLL_OUT) == PCIE_CONTROL_RST_STS_RCPHYPLL_OUT) {\r
139 break;\r
140 }\r
141 }\r
142\r
143 // Check for reset\r
144 if (!(Value & PCIE_CONTROL_RST_STS_RCPHYPLL_OUT)) {\r
145 DEBUG ((EFI_D_ERROR, "PCIe failed to come out of reset: %x.\n", Value));\r
146 return EFI_NOT_READY;\r
147 }\r
148\r
149 gBS->Stall (1000);\r
150 PCI_TRACE ("Checking link Status...");\r
151\r
152 // Wait for Link Up\r
153 for (Index = 0; Index < 1000; Index++) {\r
154 gBS->Stall (1000);\r
155 PCIE_ROOTPORT_READ32 (VEXPRESS_BASIC_STATUS, Value);\r
156 if (Value & LINK_UP) {\r
157 break;\r
158 }\r
159 }\r
160\r
161 // Check for link up\r
162 if (!(Value & LINK_UP)) {\r
163 DEBUG ((EFI_D_ERROR, "PCIe link not up: %x.\n", Value));\r
164 return EFI_NOT_READY;\r
165 }\r
166\r
167 PCIE_ROOTPORT_WRITE32 (PCIE_IMASK_LOCAL, PCIE_INT_MSI | PCIE_INT_INTx);\r
168\r
169 return EFI_SUCCESS;\r
170}\r