1/** @file
2 *
3 *  Copyright (c) 2019 Linaro, Limited. All rights reserved.
4 *  Copyright (c) 2021 Arm
5 *
6 *  SPDX-License-Identifier: BSD-2-Clause-Patent
7 *
8 **/
9
10Device(PCI0)
11{
12  Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
13  Name(_CID, EISAID("PNP0A03")) // Compatible PCI Root Bridge
14  Name(_SEG, Zero) // PCI Segment Group number
15  Name(_BBN, Zero) // PCI Base Bus Number
16  Name(_CCA, 0)    // Mark the PCI noncoherent
17
18  // PCIe can only DMA to first 3GB with early SOC's
19  // But we keep the restriction on the later ones
20  // To avoid DMA translation problems.
21  Name (_DMA, ResourceTemplate() {
22    QWordMemory (ResourceProducer,
23      ,
24      MinFixed,
25      MaxFixed,
26      NonCacheable,
27      ReadWrite,
28      0x0,
29      0x0,        // MIN
30      0xbfffffff, // MAX
31      0x0,        // TRA
32      0xc0000000, // LEN
33      ,
34      ,
35      )
36  })
37
38  // PCI Routing Table
39  Name(_PRT, Package() {
40    Package (4) { 0x0000FFFF, 0, zero, 175 },
41    Package (4) { 0x0000FFFF, 1, zero, 176 },
42    Package (4) { 0x0000FFFF, 2, zero, 177 },
43    Package (4) { 0x0000FFFF, 3, zero, 178 }
44  })
45
46  Name (_DSD, Package () {
47    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
48      Package () {
49        Package () { "linux-ecam-quirk-id", "bcm2711" },
50      }
51  })
52
53  // Root complex resources
54  Method (_CRS, 0, Serialized) {
55    Name (RBUF, ResourceTemplate () {
56
57      // bus numbers assigned to this root
58      WordBusNumber (
59        ResourceProducer,
60        MinFixed, MaxFixed, PosDecode,
61        0,   // AddressGranularity
62        0,   // AddressMinimum - Minimum Bus Number
63        255, // AddressMaximum - Maximum Bus Number
64        0,   // AddressTranslation - Set to 0
65        256  // RangeLength - Number of Busses
66      )
67
68      // 32-bit mmio window in 64-bit addr
69      QWordMemory (
70        ResourceProducer, PosDecode,
71        MinFixed, MaxFixed,
72        NonCacheable, ReadWrite,        // cacheable
73        0x00000000,                     // Granularity
74        0,                              // PCIE_PCI_MMIO_BEGIN
75        1,                              // PCIE_MMIO_LEN + PCIE_PCI_MMIO_BEGIN
76        PCIE_CPU_MMIO_WINDOW,           // PCIE_PCI_MMIO_BEGIN - PCIE_CPU_MMIO_WINDOW
77        2                               // PCIE_MMIO_LEN + 1
78        ,,,MMI1
79      )
80
81      // root port registers, not to be used if SMCCC is utilized
82      QWordMemory (
83        ResourceConsumer, ,
84        MinFixed, MaxFixed,
85        NonCacheable, ReadWrite,        // cacheable
86        0x00000000,                     // Granularity
87        0xFD500000,                     // Root port begin
88        0xFD509FFF,                     // Root port end
89        0x00000000,                     // no translation
90        0x0000A000,                     // size
91        ,,
92      )
93    }) // end Name(RBUF)
94
95    // Work around ASL's inability to add in a resource definition
96    // or for that matter compute the min,max,len properly
97    CreateQwordField (RBUF, MMI1._MIN, MMIB)
98    CreateQwordField (RBUF, MMI1._MAX, MMIE)
99    CreateQwordField (RBUF, MMI1._TRA, MMIT)
100    CreateQwordField (RBUF, MMI1._LEN, MMIL)
101    Add (MMIB, PCIE_TOP_OF_MEM_WIN, MMIB)
102    Add (PCIE_BRIDGE_MMIO_LEN, PCIE_TOP_OF_MEM_WIN, MMIE)
103    Subtract (MMIT, PCIE_TOP_OF_MEM_WIN, MMIT)
104    Add (PCIE_BRIDGE_MMIO_LEN, 1 , MMIL)
105
106    Return (RBUF)
107  } // end Method(_CRS)
108
109  // OS Control Handoff
110  Name(SUPP, Zero) // PCI _OSC Support Field value
111  Name(CTRL, Zero) // PCI _OSC Control Field value
112
113  // See [1] 6.2.10, [2] 4.5
114  Method(_OSC,4) {
115    // Note, This code is very similar to the code in the PCIe firmware
116    // specification which can be used as a reference
117    // Check for proper UUID
118    If(LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
119      // Create DWord-adressable fields from the Capabilities Buffer
120      CreateDWordField(Arg3,0,CDW1)
121      CreateDWordField(Arg3,4,CDW2)
122      CreateDWordField(Arg3,8,CDW3)
123      // Save Capabilities DWord2 & 3
124      Store(CDW2,SUPP)
125      Store(CDW3,CTRL)
126      // Mask out Native HotPlug
127      And(CTRL,0x1E,CTRL)
128      // Always allow native PME, AER (no dependencies)
129      // Never allow SHPC (no SHPC controller in this system)
130      And(CTRL,0x1D,CTRL)
131
132      If(LNotEqual(Arg1,One)) { // Unknown revision
133        Or(CDW1,0x08,CDW1)
134      }
135
136      If(LNotEqual(CDW3,CTRL)) {  // Capabilities bits were masked
137        Or(CDW1,0x10,CDW1)
138      }
139      // Update DWORD3 in the buffer
140      Store(CTRL,CDW3)
141      Return(Arg3)
142    } Else {
143      Or(CDW1,4,CDW1) // Unrecognized UUID
144      Return(Arg3)
145    }
146  } // End _OSC
147
148  Device (XHC0)
149  {
150    Name (_ADR, 0x00010000)
151    Name (_CID, "PNP0D10")
152    Name (_UID, 0x0)            // _UID: Unique ID
153    Name (_CCA, 0x0)            // _CCA: Cache Coherency Attribute
154
155    /*
156     * Microsoft's USB Device-Specific Methods. See:
157     * https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/usb-device-specific-method---dsm-
158     */
159    Name (DSMU, ToUUID ("ce2ee385-00e6-48cb-9f05-2edb927c4899"))
160
161    Method (_DSM, 4, Serialized) {
162        If (LEqual (Arg0, DSMU)) {              // USB capabilities UUID
163            Switch (ToInteger (Arg2)) {
164            Case (0) {                          // Function 0: List of supported functions
165                Return (Buffer () { 0x41 })     // 0x41 - Functions 0 and 6 supported
166            }
167            Case (6) {                          // Function 6: RegisterAccessType
168                Return (Buffer () { 0x01 })     // 0x01 - Must use 32bit register access
169            }
170            Default { }                         // Unsupported
171            }
172        }
173        return (Buffer () { 0x00 })             // Return 0x00 for anything unsupported
174    }
175  } // end XHC0
176
177} // PCI0