/** @file
|
*
|
* Copyright (c) 2019 Linaro, Limited. All rights reserved.
|
* Copyright (c) 2021 Arm
|
*
|
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
*
|
**/
|
|
#include <IndustryStandard/Bcm2711.h>
|
|
#include "AcpiTables.h"
|
|
/*
|
* The following can be used to remove parenthesis from
|
* defined macros that the compiler complains about.
|
*/
|
#define ISOLATE_ARGS(...) __VA_ARGS__
|
#define REMOVE_PARENTHESES(x) ISOLATE_ARGS x
|
|
#define SANITIZED_PCIE_CPU_MMIO_WINDOW REMOVE_PARENTHESES(PCIE_CPU_MMIO_WINDOW)
|
#define SANITIZED_PCIE_MMIO_LEN REMOVE_PARENTHESES(PCIE_BRIDGE_MMIO_LEN)
|
#define SANITIZED_PCIE_PCI_MMIO_BEGIN REMOVE_PARENTHESES(PCIE_TOP_OF_MEM_WIN)
|
|
DefinitionBlock (__FILE__, "SSDT", 5, "RPIFDN", "RPI4PCIE", 2)
|
{
|
Scope (\_SB_)
|
{
|
Device(PCI0)
|
{
|
Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
|
Name(_CID, EISAID("PNP0A03")) // Compatible PCI Root Bridge
|
Name(_SEG, Zero) // PCI Segment Group number
|
Name(_BBN, Zero) // PCI Base Bus Number
|
Name(_CCA, 0) // Mark the PCI noncoherent
|
|
// PCIe can only DMA to first 3GB with early SOC's
|
// But we keep the restriction on the later ones
|
// To avoid DMA translation problems.
|
Name (_DMA, ResourceTemplate() {
|
QWordMemory (ResourceProducer,
|
,
|
MinFixed,
|
MaxFixed,
|
NonCacheable,
|
ReadWrite,
|
0x0,
|
0x0, // MIN
|
0xbfffffff, // MAX
|
0x0, // TRA
|
0xc0000000, // LEN
|
,
|
,
|
)
|
})
|
|
// PCI Routing Table
|
Name(_PRT, Package() {
|
Package (4) { 0x0000FFFF, 0, zero, 175 },
|
Package (4) { 0x0000FFFF, 1, zero, 176 },
|
Package (4) { 0x0000FFFF, 2, zero, 177 },
|
Package (4) { 0x0000FFFF, 3, zero, 178 }
|
})
|
|
Name (_DSD, Package () {
|
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
Package () {
|
Package () { "linux-ecam-quirk-id", "bcm2711" },
|
}
|
})
|
|
// Root complex resources
|
Method (_CRS, 0, Serialized) {
|
Name (RBUF, ResourceTemplate () {
|
|
// bus numbers assigned to this root
|
WordBusNumber (
|
ResourceProducer,
|
MinFixed, MaxFixed, PosDecode,
|
0, // AddressGranularity
|
0, // AddressMinimum - Minimum Bus Number
|
255, // AddressMaximum - Maximum Bus Number
|
0, // AddressTranslation - Set to 0
|
256 // RangeLength - Number of Busses
|
)
|
|
// 32-bit mmio window in 64-bit addr
|
QWordMemory (
|
ResourceProducer, PosDecode,
|
MinFixed, MaxFixed,
|
NonCacheable, ReadWrite, // cacheable
|
0x00000000, // Granularity
|
0, // SANITIZED_PCIE_PCI_MMIO_BEGIN
|
1, // SANITIZED_PCIE_MMIO_LEN + SANITIZED_PCIE_PCI_MMIO_BEGIN
|
SANITIZED_PCIE_CPU_MMIO_WINDOW, // SANITIZED_PCIE_PCI_MMIO_BEGIN - SANITIZED_PCIE_CPU_MMIO_WINDOW
|
2 // SANITIZED_PCIE_MMIO_LEN + 1
|
,,,MMI1
|
)
|
|
// root port registers, not to be used if SMCCC is utilized
|
QWordMemory (
|
ResourceConsumer, ,
|
MinFixed, MaxFixed,
|
NonCacheable, ReadWrite, // cacheable
|
0x00000000, // Granularity
|
0xFD500000, // Root port begin
|
0xFD509FFF, // Root port end
|
0x00000000, // no translation
|
0x0000A000, // size
|
,,
|
)
|
}) // end Name(RBUF)
|
|
// Work around ASL's inability to add in a resource definition
|
// or for that matter compute the min,max,len properly
|
CreateQwordField (RBUF, MMI1._MIN, MMIB)
|
CreateQwordField (RBUF, MMI1._MAX, MMIE)
|
CreateQwordField (RBUF, MMI1._TRA, MMIT)
|
CreateQwordField (RBUF, MMI1._LEN, MMIL)
|
Add (MMIB, SANITIZED_PCIE_PCI_MMIO_BEGIN, MMIB)
|
Add (SANITIZED_PCIE_MMIO_LEN, SANITIZED_PCIE_PCI_MMIO_BEGIN, MMIE)
|
Subtract (MMIT, SANITIZED_PCIE_PCI_MMIO_BEGIN, MMIT)
|
Add (SANITIZED_PCIE_MMIO_LEN, 1 , MMIL)
|
|
Return (RBUF)
|
} // end Method(_CRS)
|
|
// OS Control Handoff
|
Name(SUPP, Zero) // PCI _OSC Support Field value
|
Name(CTRL, Zero) // PCI _OSC Control Field value
|
|
// See [1] 6.2.10, [2] 4.5
|
Method(_OSC,4) {
|
// Note, This code is very similar to the code in the PCIe firmware
|
// specification which can be used as a reference
|
// Check for proper UUID
|
If(LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
|
// Create DWord-adressable fields from the Capabilities Buffer
|
CreateDWordField(Arg3,0,CDW1)
|
CreateDWordField(Arg3,4,CDW2)
|
CreateDWordField(Arg3,8,CDW3)
|
// Save Capabilities DWord2 & 3
|
Store(CDW2,SUPP)
|
Store(CDW3,CTRL)
|
// Mask out Native HotPlug
|
And(CTRL,0x1E,CTRL)
|
// Always allow native PME, AER (no dependencies)
|
// Never allow SHPC (no SHPC controller in this system)
|
And(CTRL,0x1D,CTRL)
|
|
If(LNotEqual(Arg1,One)) { // Unknown revision
|
Or(CDW1,0x08,CDW1)
|
}
|
|
If(LNotEqual(CDW3,CTRL)) { // Capabilities bits were masked
|
Or(CDW1,0x10,CDW1)
|
}
|
// Update DWORD3 in the buffer
|
Store(CTRL,CDW3)
|
Return(Arg3)
|
} Else {
|
Or(CDW1,4,CDW1) // Unrecognized UUID
|
Return(Arg3)
|
}
|
} // End _OSC
|
} // PCI0
|
} //end scope sb
|
} //end definition block
|