new file mode 100644
@@ -0,0 +1,3 @@
+dsdt_generated.aml
+dsdt_generated.asl.tmp
+dsdt_generated.c
@@ -4,3 +4,5 @@
obj-y := rpi.o
obj-y += lowlevel_init.o
+
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt_generated.o
new file mode 100644
@@ -0,0 +1,90 @@
+/** @file
+ *
+ * RPi defines for constructing ACPI tables
+ *
+ * Copyright (c) 2020, Pete Batard <pete@akeo.ie>
+ * Copyright (c) 2019, ARM Ltd. All rights reserved.
+ * Copyright (c) 2018, Andrei Warkentin <andrey.warkentin@gmail.com>
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#ifndef __RPI_ACPITABLES_H__
+#define __RPI_ACPITABLES_H__
+
+#include <acpi/acpi_table.h>
+
+// The ASL compiler can't perform arithmetic on MEMORY32FIXED ()
+// parameters so you can't pass a constant like BASE + OFFSET.
+// We therefore define a macro that can perform arithmetic base
+// address update with an offset.
+#define MEMORY32SETBASE(BufName, MemName, VarName, Offset) \
+ CreateDwordField (^BufName, ^MemName._BAS, VarName) \
+ Add (BCM2836_SOC_REGISTERS, Offset, VarName)
+
+//------------------------------------------------------------------------
+// Interrupts. These are specific to each platform
+//------------------------------------------------------------------------
+#if defined(CONFIG_TARGET_RPI_3)
+#define BCM2836_V3D_BUS_INTERRUPT 0x2A
+#define BCM2836_DMA_INTERRUPT 0x3B
+#define BCM2836_SPI1_INTERRUPT 0x3D
+#define BCM2836_SPI2_INTERRUPT 0x3D
+#define BCM2836_HVS_INTERRUPT 0x41
+#define BCM2836_HDMI0_INTERRUPT 0x48
+#define BCM2836_HDMI1_INTERRUPT 0x49
+#define BCM2836_PV2_INTERRUPT 0x4A
+#define BCM2836_PV0_INTERRUPT 0x4D
+#define BCM2836_PV1_INTERRUPT 0x4E
+#define BCM2836_MBOX_INTERRUPT 0x61
+#define BCM2836_VCHIQ_INTERRUPT 0x62
+#define BCM2386_GPIO_INTERRUPT0 0x51
+#define BCM2386_GPIO_INTERRUPT1 0x52
+#define BCM2386_GPIO_INTERRUPT2 0x53
+#define BCM2386_GPIO_INTERRUPT3 0x54
+#define BCM2836_I2C1_INTERRUPT 0x55
+#define BCM2836_I2C2_INTERRUPT 0x55
+#define BCM2836_SPI0_INTERRUPT 0x56
+#define BCM2836_USB_INTERRUPT 0x29
+#define BCM2836_SDHOST_INTERRUPT 0x58
+#define BCM2836_MMCHS1_INTERRUPT 0x5E
+#define BCM2836_MINI_UART_INTERRUPT 0x3D
+#define BCM2836_PL011_UART_INTERRUPT 0x59
+#elif defined(CONFIG_TARGET_RPI_4)
+#define BCM2836_V3D_BUS_INTERRUPT 0x2A
+#define BCM2836_DMA_INTERRUPT 0x3B
+#define BCM2836_SPI1_INTERRUPT 0x7D
+#define BCM2836_SPI2_INTERRUPT 0x7D
+#define BCM2836_HVS_INTERRUPT 0x41
+#define BCM2836_HDMI0_INTERRUPT 0x48
+#define BCM2836_HDMI1_INTERRUPT 0x49
+#define BCM2836_PV2_INTERRUPT 0x4A
+#define BCM2836_PV0_INTERRUPT 0x4D
+#define BCM2836_PV1_INTERRUPT 0x4E
+#define BCM2836_MBOX_INTERRUPT 0x41
+#define BCM2836_VCHIQ_INTERRUPT 0x42
+#define BCM2386_GPIO_INTERRUPT0 0x91
+#define BCM2386_GPIO_INTERRUPT1 0x92
+#define BCM2386_GPIO_INTERRUPT2 0x93
+#define BCM2386_GPIO_INTERRUPT3 0x94
+#define BCM2836_I2C1_INTERRUPT 0x95
+#define BCM2836_I2C2_INTERRUPT 0x95
+#define BCM2836_SPI0_INTERRUPT 0x96
+#define BCM2836_USB_INTERRUPT 0x69
+#define BCM2836_SDHOST_INTERRUPT 0x98
+#define BCM2836_MMCHS1_INTERRUPT 0x9E
+#define BCM2836_MINI_UART_INTERRUPT 0x7D
+#define BCM2836_PL011_UART_INTERRUPT 0x99
+#define GENET_INTERRUPT0 0xBD
+#define GENET_INTERRUPT1 0xBE
+#define GENET_BASE_ADDRESS 0xFD580000
+#define GENET_LENGTH 0x10000
+#define THERM_SENSOR_BASE_ADDRESS 0xFD5d2200
+#define THERM_SENSOR_LENGTH 0x8
+#else
+#error "Unsupported rpi module for ACPI tables"
+#endif
+
+#endif // __ACPITABLES_H__
new file mode 100644
@@ -0,0 +1,290 @@
+/** @file
+ *
+ * Differentiated System Definition Table (DSDT)
+ *
+ * Copyright (c) 2020, Pete Batard <pete@akeo.ie>
+ * Copyright (c) 2018-2020, Andrey Warkentin <andrey.warkentin@gmail.com>
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Copyright (c) 2021, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#include <asm/arch/acpi/bcm2711.h>
+#include <asm/arch/acpi/bcm2836.h>
+#include <asm/arch/acpi/bcm2836_gpio.h>
+#include <asm/arch/acpi/bcm2836_gpu.h>
+#include <asm/arch/acpi/bcm2836_pwm.h>
+#include <asm/arch/acpi/bcm2836_sdio.h>
+#include <asm/arch/acpi/bcm2836_sdhost.h>
+
+#include "acpitables.h"
+
+#define BCM_ALT0 0x4
+#define BCM_ALT1 0x5
+#define BCM_ALT2 0x6
+#define BCM_ALT3 0x7
+#define BCM_ALT4 0x3
+#define BCM_ALT5 0x2
+
+//
+// The ASL compiler does not support argument arithmetic in functions
+// like QWordMemory (). So we need to instantiate dummy qword regions
+// that we can then update the Min, Max and Length attributes of.
+// The three macros below help accomplish this.
+//
+// QWORDMEMORYSET specifies a CPU memory range (whose base address is
+// BCM2836_SOC_REGISTERS + Offset), and QWORDBUSMEMORYSET specifies
+// a VPU memory range (whose base address is provided directly).
+//
+#define QWORDMEMORYBUF(Index) \
+ QWordMemory (ResourceProducer,, \
+ MinFixed, MaxFixed, NonCacheable, ReadWrite, \
+ 0x0, 0x0, 0x0, 0x0, 0x1,,, RB ## Index)
+
+#define QWORDMEMORYSET(Index, Offset, Length) \
+ CreateQwordField (RBUF, RB ## Index._MIN, MI ## Index) \
+ CreateQwordField (RBUF, RB ## Index._MAX, MA ## Index) \
+ CreateQwordField (RBUF, RB ## Index._LEN, LE ## Index) \
+ Store (Length, LE ## Index) \
+ Add (BCM2836_SOC_REGISTERS, Offset, MI ## Index) \
+ Add (MI ## Index, LE ## Index - 1, MA ## Index)
+
+#define QWORDBUSMEMORYSET(Index, Base, Length) \
+ CreateQwordField (RBUF, RB ## Index._MIN, MI ## Index) \
+ CreateQwordField (RBUF, RB ## Index._MAX, MA ## Index) \
+ CreateQwordField (RBUF, RB ## Index._LEN, LE ## Index) \
+ Store (Base, MI ## Index) \
+ Store (Length, LE ## Index) \
+ Add (MI ## Index, LE ## Index - 1, MA ## Index)
+
+DefinitionBlock ("Dsdt.aml", "DSDT", 2, "RPIFDN", "RPI", 2)
+{
+ Scope (\_SB_)
+ {
+ include ("pep.asl")
+
+ Device (CPU0)
+ {
+ Name (_HID, "ACPI0007")
+ Name (_UID, 0x0)
+ Method (_STA)
+ {
+ Return (0xf)
+ }
+ }
+
+ Device (CPU1)
+ {
+ Name (_HID, "ACPI0007")
+ Name (_UID, 0x1)
+ Method (_STA)
+ {
+ Return (0xf)
+ }
+ }
+
+ Device (CPU2)
+ {
+ Name (_HID, "ACPI0007")
+ Name (_UID, 0x2)
+ Method (_STA)
+ {
+ Return (0xf)
+ }
+ }
+
+ Device (CPU3)
+ {
+ Name (_HID, "ACPI0007")
+ Name (_UID, 0x3)
+ Method (_STA)
+ {
+ Return (0xf)
+ }
+ }
+
+ //
+ // GPU device container describes the DMA translation required
+ // when a device behind the GPU wants to access Arm memory.
+ // Only the first GB can be addressed.
+ //
+ Device (GDV0)
+ {
+ Name (_HID, "ACPI0004")
+ Name (_UID, 0x1)
+ Name (_CCA, 0x0)
+
+ Method (_CRS, 0, Serialized) {
+ //
+ // Container devices with _DMA must have _CRS, meaning GDV0
+ // to provide all resources that GpuDevs.asl consume (except
+ // interrupts).
+ //
+ Name (RBUF, ResourceTemplate () {
+ QWORDMEMORYBUF(01)
+ QWORDMEMORYBUF(02)
+ QWORDMEMORYBUF(03)
+ // QWORDMEMORYBUF(04)
+ // QWORDMEMORYBUF(05)
+ QWORDMEMORYBUF(06)
+ QWORDMEMORYBUF(07)
+ QWORDMEMORYBUF(08)
+ QWORDMEMORYBUF(09)
+ QWORDMEMORYBUF(10)
+ QWORDMEMORYBUF(11)
+ QWORDMEMORYBUF(12)
+ QWORDMEMORYBUF(13)
+ QWORDMEMORYBUF(14)
+ QWORDMEMORYBUF(15)
+ // QWORDMEMORYBUF(16)
+ QWORDMEMORYBUF(17)
+ QWORDMEMORYBUF(18)
+ QWORDMEMORYBUF(19)
+ QWORDMEMORYBUF(20)
+ QWORDMEMORYBUF(21)
+ QWORDMEMORYBUF(22)
+ QWORDMEMORYBUF(23)
+ QWORDMEMORYBUF(24)
+ QWORDMEMORYBUF(25)
+ })
+
+ // USB
+ QWORDMEMORYSET(01, BCM2836_USB_OFFSET, BCM2836_USB_LENGTH)
+
+ // GPU
+ QWORDMEMORYSET(02, BCM2836_V3D_BUS_OFFSET, BCM2836_V3D_BUS_LENGTH)
+ QWORDMEMORYSET(03, BCM2836_HVS_OFFSET, BCM2836_HVS_LENGTH)
+ // QWORDMEMORYSET(04, BCM2836_PV0_OFFSET, BCM2836_PV0_LENGTH)
+ // QWORDMEMORYSET(05, BCM2836_PV1_OFFSET, BCM2836_PV1_LENGTH)
+ QWORDMEMORYSET(06, BCM2836_PV2_OFFSET, BCM2836_PV2_LENGTH)
+ QWORDMEMORYSET(07, BCM2836_HDMI0_OFFSET, BCM2836_HDMI0_LENGTH)
+ QWORDMEMORYSET(08, BCM2836_HDMI1_OFFSET, BCM2836_HDMI1_LENGTH)
+
+ // Mailbox
+ QWORDMEMORYSET(09, BCM2836_MBOX_OFFSET, BCM2836_MBOX_LENGTH)
+
+ // VCHIQ
+ QWORDMEMORYSET(10, BCM2836_VCHIQ_OFFSET, BCM2836_VCHIQ_LENGTH)
+
+ // GPIO
+ QWORDMEMORYSET(11, GPIO_OFFSET, GPIO_LENGTH)
+
+ // I2C
+ QWORDMEMORYSET(12, BCM2836_I2C1_OFFSET, BCM2836_I2C1_LENGTH)
+ QWORDMEMORYSET(13, BCM2836_I2C2_OFFSET, BCM2836_I2C2_LENGTH)
+
+ // SPI
+ QWORDMEMORYSET(14, BCM2836_SPI0_OFFSET, BCM2836_SPI0_LENGTH)
+ QWORDMEMORYSET(15, BCM2836_SPI1_OFFSET, BCM2836_SPI1_LENGTH)
+ // QWORDMEMORYSET(16, BCM2836_SPI2_OFFSET, BCM2836_SPI2_LENGTH)
+
+ // PWM
+ QWORDMEMORYSET(17, BCM2836_PWM_DMA_OFFSET, BCM2836_PWM_DMA_LENGTH)
+ QWORDMEMORYSET(18, BCM2836_PWM_CTRL_OFFSET, BCM2836_PWM_CTRL_LENGTH)
+ QWORDBUSMEMORYSET(19, BCM2836_PWM_BUS_BASE_ADDRESS, BCM2836_PWM_BUS_LENGTH)
+ QWORDBUSMEMORYSET(20, BCM2836_PWM_CTRL_UNCACHED_BASE_ADDRESS, BCM2836_PWM_CTRL_UNCACHED_LENGTH)
+ QWORDMEMORYSET(21, BCM2836_PWM_CLK_OFFSET, BCM2836_PWM_CLK_LENGTH)
+
+ // UART
+ QWORDMEMORYSET(22, BCM2836_PL011_UART_OFFSET, BCM2836_PL011_UART_LENGTH)
+ QWORDMEMORYSET(23, BCM2836_MINI_UART_OFFSET, BCM2836_MINI_UART_LENGTH)
+
+ // SDC
+ QWORDMEMORYSET(24, MMCHS1_OFFSET, MMCHS1_LENGTH)
+ QWORDMEMORYSET(25, SDHOST_OFFSET, SDHOST_LENGTH)
+
+ Return (RBUF)
+ }
+
+ Name (_DMA, ResourceTemplate() {
+ //
+ // Only the first GB is available.
+ // Bus 0xC0000000 -> CPU 0x00000000.
+ //
+ QWordMemory (ResourceProducer,
+ ,
+ MinFixed,
+ MaxFixed,
+ NonCacheable,
+ ReadWrite,
+ 0x0,
+ 0x00000000C0000000, // MIN
+ 0x00000000FFFFFFFF, // MAX
+ 0xFFFFFFFF40000000, // TRA
+ 0x0000000040000000, // LEN
+ ,
+ ,
+ )
+ })
+#include "gpudevs.asl"
+ }
+
+#if defined(CONFIG_TARGET_RPI_4)
+ Device (ETH0)
+ {
+ Name (_HID, "BCM6E4E")
+ Name (_CID, "BCM6E4E")
+ Name (_UID, 0x0)
+ Name (_CCA, 0x0)
+
+ Method (_CRS, 0x0, Serialized)
+ {
+ Return (ResourceTemplate ()
+ {
+ // No need for MEMORY32SETBASE on Genet as we have a straight base address constant
+ MEMORY32FIXED (ReadWrite, GENET_BASE_ADDRESS, GENET_LENGTH, )
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { GENET_INTERRUPT0, GENET_INTERRUPT1 }
+ })
+ }
+ Name (_DSD, Package () {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package () {
+ Package () { "brcm,max-dma-burst-size", 0x08 },
+ Package () { "phy-mode", "rgmii-rxid" },
+ }
+ })
+ }
+
+ // Define a simple thermal zone. The idea here is we compute the SOC temp
+ // via a register we can read, and give it to the OS. This enables basic
+ // reports from the "sensors" utility, and the OS can then poll and take
+ // actions if that temp exceeds any of the given thresholds.
+ Device (EC00)
+ {
+ Name (_HID, EISAID ("PNP0C06"))
+ Name (_CCA, 0x0)
+
+ // all temps in are tenths of K (aka 2732 is the min temps in Linux (aka 0C))
+ ThermalZone (TZ00) {
+ OperationRegion (TEMS, SystemMemory, THERM_SENSOR_BASE_ADDRESS, THERM_SENSOR_LENGTH)
+ Field (TEMS, DWordAcc, NoLock, Preserve) {
+ TMPS, 32
+ }
+ Method (_TMP, 0, Serialized) {
+ return (((410040 - ((TMPS & 0x3ff) * 487)) / 100) + 2732);
+ }
+
+ Method (_SCP, 3) { } // receive cooling policy from OS
+
+ Method (_CRT) { Return (3632) } // (90C) Critical temp point (immediate power-off)
+ Method (_HOT) { Return (3582) } // (85C) HOT state where OS should hibernate
+ Method (_PSV) { Return (3532) } // (80C) Passive cooling (CPU throttling) trip point
+
+ // SSDT inserts _AC0/_AL0 @60C here, if a FAN is configured
+
+ Name (_TZP, 10) //The OSPM must poll this device every 1 seconds
+ Name (_PSL, Package () { \_SB_.CPU0, \_SB_.CPU1, \_SB_.CPU2, \_SB_.CPU3 })
+ }
+ }
+#endif
+
+
+#include "uart.asl"
+#include "rhpx.asl"
+#include "sdhc.asl"
+#include "emmc.asl"
+#include "pci.asl"
+ }
+}
new file mode 100644
@@ -0,0 +1,136 @@
+/** @file
+ *
+ * Copyright (c) 2021, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#include <asm/arch/acpi/bcm2836_sdhost.h>
+#include <asm/arch/acpi/bcm2836_sdio.h>
+#include <asm/arch/acpi/bcm2711.h>
+
+Device (GDV1) {
+ Name (_HID, "ACPI0004")
+ Name (_UID, 0x2)
+ Name (_CCA, 0x0)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, MMCHS2_LENGTH, RMEM)
+ })
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, MMCHS2_OFFSET)
+ Return (^RBUF)
+ }
+
+ // Translated DMA region for BCM2711 silicon revisions older than C0
+ Name (DMTR, ResourceTemplate() {
+ QWordMemory (ResourceProducer,
+ ,
+ MinFixed,
+ MaxFixed,
+ NonCacheable,
+ ReadWrite,
+ 0x0,
+ 0x00000000C0000000, // MIN
+ 0x00000000FFFFFFFF, // MAX
+ 0xFFFFFFFF40000000, // TRA
+ 0x0000000040000000, // LEN
+ ,
+ ,
+ )
+ })
+
+ // Non translated DMA region for BCM2711 revisions C0 and newer
+ Name (DMNT, ResourceTemplate() {
+ QWordMemory (ResourceProducer,
+ ,
+ MinFixed,
+ MaxFixed,
+ NonCacheable,
+ ReadWrite,
+ 0x0,
+ 0x0000000000000000, // MIN
+ 0x000000FFFFFFFFFF, // MAX
+ 0x0000000000000000, // TRA
+ 0x0000010000000000, // LEN
+ ,
+ ,
+ )
+ })
+
+ // emmc2 Host Controller. (brcm,bcm2711-emmc2)
+ Device (SDC3)
+ {
+ Name (_HID, "BRCME88C")
+ Name (_UID, 0x1)
+ Name (_CCA, 0x0)
+ Name (_S1D, 0x1)
+ Name (_S2D, 0x1)
+ Name (_S3D, 0x1)
+ Name (_S4D, 0x1)
+ Name (SDMA, 0x2)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, MMCHS2_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_MMCHS1_INTERRUPT }
+ })
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, MMCHS2_OFFSET)
+ Return (^RBUF)
+ }
+
+ // Unfortunately this controller doesn't honor the
+ // standard SDHCI voltage control registers
+ // (or at least Linux's standard code can't
+ // lower the voltage) So, UHS mode is disabled with caps
+ Name (DSD1, Package () {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package () {
+ Package () { "sdhci-caps-mask", 0x0000000500080000 },
+ }
+ })
+ // Along with disabling UHS, here both SDMA and ADMA2
+ // are also disabled until the linux _DMA() mask/translate
+ // works properly.
+ Name (DSD2, Package () {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package () {
+ Package () { "sdhci-caps-mask", 0x0000000504480000 },
+ }
+ })
+ Method (_DSD, 0x0, Serialized)
+ {
+ // Select one of the sdhci-caps-mask definitions
+ // depending on whether we also want to disable DMA
+ if (SDMA == 0)
+ {
+ return (^DSD2)
+ }
+ else
+ {
+ return (^DSD1)
+ }
+ }
+
+ //
+ // A child device that represents the
+ // sd card, which is marked as non-removable.
+ //
+ Device (SDMM)
+ {
+ Method (_ADR)
+ {
+ Return (0)
+ }
+ Method (_RMV) // Is removable
+ {
+ Return (0) // 0 - fixed
+ }
+ }
+ } //SDC3
+} //GDV1
new file mode 100644
@@ -0,0 +1,372 @@
+/** @file
+ *
+ * [DSDT] Devices behind the GPU.
+ *
+ * Copyright (c) 2018-2020, Andrey Warkentin <andrey.warkentin@gmail.com>
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+// DWC OTG Controller
+Device (USB0)
+{
+ Name (_HID, "BCM2848")
+#if defined(CONFIG_TARGET_RPI_3)
+ Name (_CID, "DWC_OTG")
+#elif defined(CONFIG_TARGET_RPI_4)
+ Name (_CID, "BCM2848")
+#endif
+ Name (_UID, 0x0)
+ Name (_CCA, 0x0)
+ Method (_STA)
+ {
+ Return (0xf)
+ }
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_USB_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_USB_INTERRUPT }
+ })
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_USB_OFFSET)
+ Return (^RBUF)
+ }
+}
+
+// Video Core 4 GPU
+Device (GPU0)
+{
+ Name (_HID, "BCM2850")
+ Name (_CID, "BCM2850")
+ Name (_UID, 0x0)
+ Name (_CCA, 0x0)
+ Method (_STA)
+ {
+ Return (0xf)
+ }
+ Name (RBUF, ResourceTemplate ()
+ {
+ // Memory and interrupt for the GPU
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_V3D_BUS_LENGTH, RM01)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_V3D_BUS_INTERRUPT }
+
+ // HVS - Hardware Video Scalar
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_HVS_LENGTH, RM02)
+ // The HVS interrupt is reserved by the VPU
+ // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_HVS_INTERRUPT }
+
+ // PixelValve0 - DSI0 or DPI
+ // MEMORY32FIXED (ReadWrite, BCM2836_PV0_BASE_ADDRESS, BCM2836_PV0_LENGTH, RM03)
+ // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PV0_INTERRUPT }
+
+ // PixelValve1 - DS1 or SMI
+ // MEMORY32FIXED (ReadWrite, BCM2836_PV1_BASE_ADDRESS, BCM2836_PV1_LENGTH, RM04)
+ // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PV1_INTERRUPT }
+
+ // PixelValve2 - HDMI output - connected to HVS display FIFO 1
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_PV2_LENGTH, RM05)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PV2_INTERRUPT }
+
+ // HDMI registers
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_HDMI0_LENGTH, RM06)
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_HDMI1_LENGTH, RM07)
+ // hdmi_int[0]
+ // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_HDMI0_INTERRUPT }
+ // hdmi_int[1]
+ // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_HDMI1_INTERRUPT }
+
+ // HDMI DDC connection
+ I2CSerialBus (0x50,, 100000,, "\\_SB.GDV0.I2C2",,,,) // EDID
+ I2CSerialBus (0x30,, 100000,, "\\_SB.GDV0.I2C2",,,,) // E-DDC Segment Pointer
+ })
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RM01, RB01, BCM2836_V3D_BUS_OFFSET)
+ MEMORY32SETBASE (RBUF, RM02, RB02, BCM2836_HVS_OFFSET)
+ MEMORY32SETBASE (RBUF, RM05, RB05, BCM2836_PV2_OFFSET)
+ MEMORY32SETBASE (RBUF, RM06, RB06, BCM2836_HDMI0_OFFSET)
+ MEMORY32SETBASE (RBUF, RM07, RB07, BCM2836_HDMI1_OFFSET)
+ Return (^RBUF)
+ }
+
+ // GPU Power Management Component Data
+ // Reference : https://github.com/Microsoft/graphics-driver-samples/wiki/Install-Driver-in-a-Windows-VM
+ Method (PMCD, 0, Serialized)
+ {
+ Name (RBUF, Package ()
+ {
+ 1, // Version
+ 1, // Number of graphics power components
+ Package () // Power components package
+ {
+ Package () // GPU component package
+ {
+ 0, // Component Index
+ 0, // DXGK_POWER_COMPONENT_MAPPING.ComponentType (0 = DXGK_POWER_COMPONENT_ENGINE)
+ 0, // DXGK_POWER_COMPONENT_MAPPING.NodeIndex
+
+ Buffer () // DXGK_POWER_RUNTIME_COMPONENT.ComponentGuid
+ { // 9B2D1E26-1575-4747-8FC0-B9EB4BAA2D2B
+ 0x26, 0x1E, 0x2D, 0x9B, 0x75, 0x15, 0x47, 0x47,
+ 0x8f, 0xc0, 0xb9, 0xeb, 0x4b, 0xaa, 0x2d, 0x2b
+ },
+
+ "VC4_Engine_00",// DXGK_POWER_RUNTIME_COMPONENT.ComponentName
+ 2, // DXGK_POWER_RUNTIME_COMPONENT.StateCount
+
+ Package () // DXGK_POWER_RUNTIME_COMPONENT.States[] package
+ {
+ Package () // F0
+ {
+ 0, // DXGK_POWER_RUNTIME_STATE.TransitionLatency
+ 0, // DXGK_POWER_RUNTIME_STATE.ResidencyRequirement
+ 1210000, // DXGK_POWER_RUNTIME_STATE.NominalPower (microwatt)
+ },
+
+ Package () // F1 - Placeholder
+ {
+ 10000, // DXGK_POWER_RUNTIME_STATE.TransitionLatency
+ 10000, // DXGK_POWER_RUNTIME_STATE.ResidencyRequirement
+ 4, // DXGK_POWER_RUNTIME_STATE.NominalPower
+ },
+ }
+ }
+ }
+ })
+ Return (RBUF)
+ }
+}
+
+// PiQ Mailbox Driver
+Device (RPIQ)
+{
+ Name (_HID, "BCM2849")
+ Name (_CID, "BCM2849")
+ Name (_UID, 0)
+ Name (_CCA, 0x0)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_MBOX_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_MBOX_INTERRUPT }
+ })
+
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_MBOX_OFFSET)
+ Return (^RBUF)
+ }
+}
+
+// VCHIQ Driver
+Device (VCIQ)
+{
+ Name (_HID, "BCM2835")
+ Name (_CID, "BCM2835")
+ Name (_UID, 0)
+ Name (_CCA, 0x0)
+ Name (_DEP, Package() { \_SB.GDV0.RPIQ })
+ Method (_STA)
+ {
+ Return (0xf)
+ }
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_VCHIQ_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_VCHIQ_INTERRUPT }
+ })
+
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_VCHIQ_OFFSET)
+ Return (^RBUF)
+ }
+}
+
+// VC Shared Memory Driver
+Device (VCSM)
+{
+ Name (_HID, "BCM2856")
+ Name (_CID, "BCM2856")
+ Name (_UID, 0)
+ Name (_CCA, 0x0)
+ Name (_DEP, Package() { \_SB.GDV0.VCIQ })
+ Method (_STA)
+ {
+ Return (0xf)
+ }
+}
+
+// Description: GPIO
+Device (GPI0)
+{
+ Name (_HID, "BCM2845")
+ Name (_CID, "BCM2845")
+ Name (_UID, 0x0)
+ Name (_CCA, 0x0)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, GPIO_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Shared)
+ {
+ BCM2386_GPIO_INTERRUPT0, BCM2386_GPIO_INTERRUPT1,
+ BCM2386_GPIO_INTERRUPT2, BCM2386_GPIO_INTERRUPT3
+ }
+ })
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, GPIO_OFFSET)
+ Return (^RBUF)
+ }
+}
+
+// Description: I2C
+Device (I2C1)
+{
+ Name (_HID, "BCM2841")
+ Name (_CID, "BCM2841")
+ Name (_UID, 0x1)
+ Name (_CCA, 0x0)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_I2C1_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_I2C1_INTERRUPT }
+ PinFunction (Exclusive, PullUp, BCM_ALT0, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 2, 3 }
+ })
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_I2C1_OFFSET)
+ Return (^RBUF)
+ }
+}
+
+// I2C2 is the HDMI DDC connection
+Device (I2C2)
+{
+ Name (_HID, "BCM2841")
+ Name (_CID, "BCM2841")
+ Name (_UID, 0x2)
+ Name (_CCA, 0x0)
+
+ Name (RBUF, ResourceTemplate()
+ {
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_I2C2_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_I2C2_INTERRUPT }
+ })
+
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_I2C2_OFFSET)
+ Return (^RBUF)
+ }
+}
+
+// SPI
+Device (SPI0)
+{
+ Name (_HID, "BCM2838")
+ Name (_CID, "BCM2838")
+ Name (_UID, 0x0)
+ Name (_CCA, 0x0)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_SPI0_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_SPI0_INTERRUPT }
+ PinFunction (Exclusive, PullDown, BCM_ALT0, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 9, 10, 11 } // MISO, MOSI, SCLK
+ PinFunction (Exclusive, PullUp, BCM_ALT0, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 8 } // CE0
+ PinFunction (Exclusive, PullUp, BCM_ALT0, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 7 } // CE1
+ })
+
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_SPI0_OFFSET)
+ Return (^RBUF)
+ }
+}
+
+Device (SPI1)
+{
+ Name (_HID, "BCM2839")
+ Name (_CID, "BCM2839")
+ Name (_UID, 0x1)
+ Name (_CCA, 0x0)
+ Name (_DEP, Package() { \_SB.GDV0.RPIQ })
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_SPI1_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Shared,) { BCM2836_SPI1_INTERRUPT }
+ PinFunction (Exclusive, PullDown, BCM_ALT4, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 19, 20, 21 } // MISO, MOSI, SCLK
+ PinFunction (Exclusive, PullDown, BCM_ALT4, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 16 } // CE2
+ })
+
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_SPI1_OFFSET)
+ Return (^RBUF)
+ }
+}
+
+// SPI2 has no pins on GPIO header
+// Device (SPI2)
+// {
+// Name (_HID, "BCM2839")
+// Name (_CID, "BCM2839")
+// Name (_UID, 0x2)
+// Name (_CCA, 0x0)
+// Name (_DEP, Package() { \_SB.GDV0.RPIQ })
+// Method (_STA)
+// {
+// Return (0xf) // Disabled
+// }
+// Method (_CRS, 0x0, Serialized)
+// {
+// Name (RBUF, ResourceTemplate ()
+// {
+// MEMORY32FIXED (ReadWrite, BCM2836_SPI2_BASE_ADDRESS, BCM2836_SPI2_LENGTH, RMEM)
+// Interrupt (ResourceConsumer, Level, ActiveHigh, Shared,) { BCM2836_SPI2_INTERRUPT }
+// })
+// Return (RBUF)
+// }
+// }
+
+// PWM Driver
+Device (PWM0)
+{
+ Name (_HID, "BCM2844")
+ Name (_CID, "BCM2844")
+ Name (_UID, 0)
+ Name (_CCA, 0x0)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ // DMA channel 11 control
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_PWM_DMA_LENGTH, RM01)
+ // PWM control
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_PWM_CTRL_LENGTH, RM02)
+ // PWM control bus
+ MEMORY32FIXED (ReadWrite, BCM2836_PWM_BUS_BASE_ADDRESS, BCM2836_PWM_BUS_LENGTH, )
+ // PWM control uncached
+ MEMORY32FIXED (ReadWrite, BCM2836_PWM_CTRL_UNCACHED_BASE_ADDRESS, BCM2836_PWM_CTRL_UNCACHED_LENGTH, )
+ // PWM clock control
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_PWM_CLK_LENGTH, RM03)
+ // Interrupt DMA channel 11
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_DMA_INTERRUPT }
+ // DMA channel 11, DREQ 5 for PWM
+ FixedDMA (5, 11, Width32Bit, )
+ })
+
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RM01, RB01, BCM2836_PWM_DMA_OFFSET)
+ MEMORY32SETBASE (RBUF, RM02, RB02, BCM2836_PWM_CTRL_OFFSET)
+ MEMORY32SETBASE (RBUF, RM03, RB03, BCM2836_PWM_CLK_OFFSET)
+ Return (^RBUF)
+ }
+}
\ No newline at end of file
new file mode 100644
@@ -0,0 +1,177 @@
+/** @file
+ *
+ * Copyright (c) 2019 Linaro, Limited. All rights reserved.
+ * Copyright (c) 2021 Arm
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+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, // PCIE_PCI_MMIO_BEGIN
+ 1, // PCIE_MMIO_LEN + PCIE_PCI_MMIO_BEGIN
+ PCIE_CPU_MMIO_WINDOW, // PCIE_PCI_MMIO_BEGIN - PCIE_CPU_MMIO_WINDOW
+ 2 // 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, PCIE_TOP_OF_MEM_WIN, MMIB)
+ Add (PCIE_BRIDGE_MMIO_LEN, PCIE_TOP_OF_MEM_WIN, MMIE)
+ Subtract (MMIT, PCIE_TOP_OF_MEM_WIN, MMIT)
+ Add (PCIE_BRIDGE_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
+
+ Device (XHC0)
+ {
+ Name (_ADR, 0x00010000)
+ Name (_CID, "PNP0D10")
+ Name (_UID, 0x0) // _UID: Unique ID
+ Name (_CCA, 0x0) // _CCA: Cache Coherency Attribute
+
+ /*
+ * Microsoft's USB Device-Specific Methods. See:
+ * https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/usb-device-specific-method---dsm-
+ */
+ Name (DSMU, ToUUID ("ce2ee385-00e6-48cb-9f05-2edb927c4899"))
+
+ Method (_DSM, 4, Serialized) {
+ If (LEqual (Arg0, DSMU)) { // USB capabilities UUID
+ Switch (ToInteger (Arg2)) {
+ Case (0) { // Function 0: List of supported functions
+ Return (Buffer () { 0x41 }) // 0x41 - Functions 0 and 6 supported
+ }
+ Case (6) { // Function 6: RegisterAccessType
+ Return (Buffer () { 0x01 }) // 0x01 - Must use 32bit register access
+ }
+ Default { } // Unsupported
+ }
+ }
+ return (Buffer () { 0x00 }) // Return 0x00 for anything unsupported
+ }
+ } // end XHC0
+
+} // PCI0
\ No newline at end of file
new file mode 100644
@@ -0,0 +1,90 @@
+/** @file
+ *
+ * Platform Extension Plugin (PEP).
+ *
+ * Copyright (c) 2019, ARM Ltd. All rights reserved.
+ * Copyright (c) 2018, Andrey Warkentin <andrey.warkentin@gmail.com>
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+Device(PEPD)
+{
+ //
+ // PEP virtual device.
+ //
+ Name (_HID, "BCM2854") // Note: Since PEP on RPi is a virtual device,
+ Name (_CID, "BCM2854") // its device id needs to be generated by Microsoft
+ Name (_UID, 0x0)
+ Name (_CRS, ResourceTemplate ()
+ {
+ // No hardware resources for PEP driver are needed.
+ })
+
+ //
+ // Processor info. PEP proprietary method to return
+ // PEP_PROCESSOR_TABLE_PLAT structure.
+ //
+ // See Pep.h and Pep.c.
+ //
+ Name (_GPI, Buffer()
+ {
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x5F, 0x00, 0x53,
+ 0x00, 0x42, 0x00, 0x2E, 0x00, 0x43, 0x00, 0x50, 0x00, 0x55, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ })
+
+ //
+ // Coordinated state info. PEP proprietary method to return
+ // PEP_COORDINATED_STATE_TABLE_PLAT structure.
+ //
+ // See Pep.h and Pep.c.
+ //
+ Name (_GCI, Buffer()
+ {
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+ })
+
+ //
+ // Device info. PEP proprietary method to return
+ // PEP_DEVICE_TABLE_PLAT structure.
+ //
+ // See Pep.h and Pep.c.
+ //
+ Name (_GDI, Buffer()
+ {
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x5F, 0x00, 0x53,
+ 0x00, 0x42, 0x00, 0x2E, 0x00, 0x49, 0x00, 0x32, 0x00, 0x43, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ })
+}
new file mode 100644
@@ -0,0 +1,195 @@
+/** @file
+ *
+ * [DSDT] RHProxy device to enable WinRT API (RHPX)
+ *
+ * Copyright (c) 2018, Andrey Warkentin <andrey.warkentin@gmail.com>
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+Device (RHPX)
+{
+ Name (_HID, "MSFT8000")
+ Name (_CID, "MSFT8000")
+ Name (_UID, 1)
+
+ Name(_CRS, ResourceTemplate ()
+ {
+ // Index 0
+ SPISerialBus ( // SCKL - GPIO 11 - Pin 23
+ // MOSI - GPIO 10 - Pin 19
+ // MISO - GPIO 9 - Pin 21
+ // CE0 - GPIO 8 - Pin 24
+ 0, // Device selection (CE0)
+ PolarityLow, // Device selection polarity
+ FourWireMode, // WireMode
+ 8, // DataBit len
+ ControllerInitiated, // Slave mode
+ 4000000, // Connection speed
+ ClockPolarityLow, // Clock polarity
+ ClockPhaseFirst, // Clock phase
+ "\\_SB.GDV0.SPI0", // ResourceSource: SPI bus controller name
+ 0, // ResourceSourceIndex
+ // Resource usage
+ // DescriptorName: creates name for offset of resource descriptor
+ ) // Vendor Data
+
+ // Index 1
+ SPISerialBus ( // SCKL - GPIO 11 - Pin 23
+ // MOSI - GPIO 10 - Pin 19
+ // MISO - GPIO 9 - Pin 21
+ // CE1 - GPIO 7 - Pin 26
+ 1, // Device selection (CE1)
+ PolarityLow, // Device selection polarity
+ FourWireMode, // WireMode
+ 8, // DataBit len
+ ControllerInitiated, // Slave mode
+ 4000000, // Connection speed
+ ClockPolarityLow, // Clock polarity
+ ClockPhaseFirst, // Clock phase
+ "\\_SB.GDV0.SPI0", // ResourceSource: SPI bus controller name
+ 0, // ResourceSourceIndex
+ // Resource usage
+ // DescriptorName: creates name for offset of resource descriptor
+ ) // Vendor Data
+
+ // Index 2
+ I2CSerialBus ( // Pin 3 (GPIO2, SDA1), 5 (GPIO3, SCL1)
+ 0xFFFF, // SlaveAddress: placeholder
+ , // SlaveMode: default to ControllerInitiated
+ 0, // ConnectionSpeed: placeholder
+ , // Addressing Mode: default to 7 bit
+ "\\_SB.GDV0.I2C1", // ResourceSource: I2C bus controller name
+ ,
+ ,
+ , // Descriptor Name: creates name for offset of resource descriptor
+ ) // Vendor Data
+
+ // Index 3
+ SPISerialBus ( // SPI1_SCLK - GPIO21
+ // SPI1_MOSI - GPIO20
+ // SPI1_MISO - GPIO19
+ // SPI1_CE2_N - GPIO16
+ 2, // Device selection (CE2)
+ PolarityLow, // Device selection polarity
+ FourWireMode, // WireMode
+ 8, // DataBit len
+ ControllerInitiated, // Slave mode
+ 4000000, // Connection speed
+ ClockPolarityLow, // Clock polarity
+ ClockPhaseFirst, // Clock phase
+ "\\_SB.GDV0.SPI1", // ResourceSource: SPI bus controller name
+ 0, // ResourceSourceIndex
+ // Resource usage
+ // DescriptorName: creates name for offset of resource descriptor
+ ) // Vendor Data
+
+ // GPIO 2
+ GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 2 }
+ GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 2 }
+ // GPIO 3
+ GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 3 }
+ GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 3 }
+ // GPIO 4
+ GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 4 }
+ GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 4 }
+ // GPIO 5
+ GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 5 }
+ GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 5 }
+ // GPIO 6
+ GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 6 }
+ GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 6 }
+ // GPIO 7
+ GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 7 }
+ GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 7 }
+ // GPIO 8
+ GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 8 }
+ GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 8 }
+ // GPIO 9
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 9 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 9 }
+ // GPIO 10
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 10 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 10 }
+ // GPIO 11
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 11 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 11 }
+ // GPIO 12
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 12 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 12 }
+ // GPIO 13
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 13 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 13 }
+ // NTRAID#MSFT-7141401-2016/04/7-jordanrh - disable UART muxing
+ // until a proper solution can be created for the dmap conflict
+ // GPIO 14 - UART TX
+ // GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 14 }
+ // GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 14 }
+ // GPIO 15 - UART RX
+ // GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 15 }
+ // GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 15 }
+ // GPIO 16
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 16 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 16 }
+ // GPIO 17
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 17 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 17 }
+ // GPIO 18
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 18 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 18 }
+ // GPIO 19
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 19 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 19 }
+ // GPIO 20
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 20 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 20 }
+ // GPIO 21
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 21 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 21 }
+ // GPIO 22
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 22 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 22 }
+ // GPIO 23
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 23 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 23 }
+ // GPIO 24
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 24 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 24 }
+ // GPIO 25
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 25 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 25 }
+ // GPIO 26
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 26 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 26 }
+ // GPIO 27
+ GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 27 }
+ GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 27 }
+ })
+
+ Name (_DSD, Package()
+ {
+ ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package ()
+ {
+ // Reference http://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md
+ // SPI 0
+ Package (2) { "bus-SPI-SPI0", Package() { 0, 1 } }, // Index 0 & 1
+ Package (2) { "SPI0-MinClockInHz", 7629 }, // 7629 Hz
+ Package (2) { "SPI0-MaxClockInHz", 125000000 }, // 125 MHz
+ Package (2) { "SPI0-SupportedDataBitLengths", Package() { 8 } }, // Data Bit Length
+ // I2C1
+ Package (2) { "bus-I2C-I2C1", Package() { 2 } },
+ // GPIO Pin Count and supported drive modes
+ Package (2) { "GPIO-PinCount", 54 },
+ Package (2) { "GPIO-UseDescriptorPinNumbers", 1 },
+ Package (2) { "GPIO-SupportedDriveModes", 0xf }, // InputHighImpedance, InputPullUp, InputPullDown, OutputCmos
+ // SPI 1
+ Package (2) { "bus-SPI-SPI1", Package() { 3 }}, // Index 3
+ Package (2) { "SPI1-MinClockInHz", 30511 }, // 30.5 kHz
+ Package (2) { "SPI1-MaxClockInHz", 20000000 }, // 20 MHz
+ Package (2) { "SPI1-SupportedDataBitLengths", Package() { 8 } }, // Data Bit Length
+ }
+ })
+}
@@ -23,6 +23,11 @@
#endif
#include <watchdog.h>
#include <dm/pinctrl.h>
+#include <dm/ofnode.h>
+#include <acpi/acpi_table.h>
+#include <acpi/acpigen.h>
+#include <dm/lists.h>
+#include <tables_csum.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -583,3 +588,181 @@ int ft_board_setup(void *blob, struct bd_info *bd)
return 0;
}
+
+#if CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE)
+static bool is_rpi4(void)
+{
+ return of_machine_is_compatible("brcm,bcm2711") ||
+ of_machine_is_compatible("brcm,bcm2712");
+}
+
+static bool is_rpi3(void)
+{
+ return of_machine_is_compatible("brcm,bcm2837");
+}
+
+static int acpi_rpi_board_fill_ssdt(struct acpi_ctx *ctx)
+{
+ int node, ret, uart_in_use, mini_clock_rate;
+ bool enabled;
+ struct udevice *dev;
+ struct {
+ const char *fdt_compatible;
+ const char *acpi_scope;
+ bool on_rpi4;
+ bool on_rpi3;
+ u32 mmio_address;
+ } map[] = {
+ {"brcm,bcm2711-pcie", "\\_SB.PCI0", true, false},
+ {"brcm,bcm2711-emmc2", "\\_SB.GDV1.SDC3", true, false},
+ {"brcm,bcm2835-pwm", "\\_SB.GDV0.PWM0", true, true},
+ {"brcm,bcm2711-genet-v5", "\\_SB.ETH0", true, false},
+ {"brcm,bcm2711-thermal", "\\_SB.EC00", true, true},
+ {"brcm,bcm2835-sdhci", "\\_SB.SDC1", true, true},
+ {"brcm,bcm2835-sdhost", "\\_SB.SDC2", false, true},
+ {"brcm,bcm2835-mbox", "\\_SB.GDV0.RPIQ", true, true},
+ {"brcm,bcm2835-i2c", "\\_SB.GDV0.I2C1", true, true, 0xfe205000},
+ {"brcm,bcm2835-i2c", "\\_SB.GDV0.I2C2", true, true, 0xfe804000},
+ {"brcm,bcm2835-spi", "\\_SB.GDV0.SPI0", true, true},
+ {"brcm,bcm2835-aux-spi", "\\_SB.GDV0.SPI1", true, true, 0xfe215080},
+ {"arm,pl011", "\\_SB.URT0", true, true},
+ {"brcm,bcm2835-aux-uart", "\\_SB.URTM", true, true},
+ { /* Sentinel */ }
+ };
+
+ /* Device enable */
+ for (int i = 0; map[i].fdt_compatible; i++) {
+ if ((is_rpi4() && !map[i].on_rpi4) ||
+ (is_rpi3() && !map[i].on_rpi3)) {
+ enabled = false;
+ } else {
+ node = fdt_node_offset_by_compatible(gd->fdt_blob, -1,
+ map[i].fdt_compatible);
+ while (node != -FDT_ERR_NOTFOUND && map[i].mmio_address) {
+ struct fdt_resource r;
+
+ ret = fdt_get_resource(gd->fdt_blob, node, "reg", 0, &r);
+ if (ret) {
+ node = -FDT_ERR_NOTFOUND;
+ break;
+ }
+
+ if (r.start == map[i].mmio_address)
+ break;
+
+ node = fdt_node_offset_by_compatible(gd->fdt_blob, node,
+ map[i].fdt_compatible);
+ }
+
+ enabled = (node > 0) ? fdtdec_get_is_enabled(gd->fdt_blob, node) : 0;
+ }
+ acpigen_write_scope(ctx, map[i].acpi_scope);
+ acpigen_write_name_integer(ctx, "_STA", enabled ? 0xf : 0);
+ acpigen_pop_len(ctx);
+ }
+
+ /* GPIO quirks */
+ node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "brcm,bcm2835-gpio");
+ if (node <= 0)
+ node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "brcm,bcm2711-gpio");
+
+ acpigen_write_scope(ctx, "\\_SB.GDV0.GPI0");
+ enabled = (node > 0) ? fdtdec_get_is_enabled(gd->fdt_blob, node) : 0;
+ acpigen_write_name_integer(ctx, "_STA", enabled ? 0xf : 0);
+ acpigen_pop_len(ctx);
+
+ if (is_rpi4()) {
+ /* eMMC quirks */
+ node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "brcm,bcm2711-emmc2");
+ if (node) {
+ phys_addr_t cpu;
+ dma_addr_t bus;
+ u64 size;
+
+ ret = fdt_get_dma_range(gd->fdt_blob, node, &cpu, &bus, &size);
+
+ acpigen_write_scope(ctx, "\\_SB.GDV1");
+ acpigen_write_method_serialized(ctx, "_DMA", 0);
+ acpigen_emit_byte(ctx, RETURN_OP);
+
+ if (!ret && bus != cpu) /* Translated DMA range */
+ acpigen_emit_namestring(ctx, "\\_SB.GDV1.DMTR");
+ else if (!ret && bus == cpu) /* Non translated DMA */
+ acpigen_emit_namestring(ctx, "\\_SB.GDV1.DMNT");
+ else /* Silicon revisions older than C0: Translated DMA range */
+ acpigen_emit_namestring(ctx, "\\_SB.GDV1.DMTR");
+ acpigen_pop_len(ctx);
+ }
+ }
+
+ /* Serial */
+ uart_in_use = ~0;
+ mini_clock_rate = 0x1000000;
+
+ ret = uclass_get_device_by_driver(UCLASS_SERIAL,
+ DM_DRIVER_GET(bcm283x_pl011_uart),
+ &dev);
+ if (!ret)
+ uart_in_use = 0;
+
+ ret = uclass_get_device_by_driver(UCLASS_SERIAL,
+ DM_DRIVER_GET(serial_bcm283x_mu),
+ &dev);
+ if (!ret) {
+ if (uart_in_use == 0)
+ log_err("Invalid config: PL011 and MiniUART are both enabled.");
+ else
+ uart_in_use = 1;
+
+ mini_clock_rate = dev_read_u32_default(dev, "clock", 0x1000000);
+ }
+ if (uart_in_use > 1)
+ log_err("No working serial: PL011 and MiniUART are both disabled.");
+
+ acpigen_write_scope(ctx, "\\_SB.BTH0");
+ acpigen_write_name_integer(ctx, "URIU", uart_in_use);
+ acpigen_pop_len(ctx);
+
+ acpigen_write_scope(ctx, "\\_SB.URTM");
+ acpigen_write_name_integer(ctx, "MUCR", mini_clock_rate);
+ acpigen_pop_len(ctx);
+
+ return 0;
+}
+
+static int rpi_acpi_write_ssdt(struct acpi_ctx *ctx, const struct acpi_writer *entry)
+{
+ struct acpi_table_header *ssdt;
+ int ret;
+
+ ssdt = ctx->current;
+ memset(ssdt, '\0', sizeof(struct acpi_table_header));
+
+ acpi_fill_header(ssdt, "SSDT");
+ ssdt->revision = acpi_get_table_revision(ACPITAB_SSDT);
+ ssdt->creator_revision = 1;
+ ssdt->length = sizeof(struct acpi_table_header);
+
+ acpi_inc(ctx, sizeof(struct acpi_table_header));
+
+ ret = acpi_rpi_board_fill_ssdt(ctx);
+ if (ret) {
+ ctx->current = ssdt;
+ return log_msg_ret("fill", ret);
+ }
+
+ /* (Re)calculate length and checksum */
+ ssdt->length = ctx->current - (void *)ssdt;
+ ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length);
+ log_debug("SSDT at %p, length %x\n", ssdt, ssdt->length);
+
+ /* Drop the table if it is empty */
+ if (ssdt->length == sizeof(struct acpi_table_header))
+ return log_msg_ret("fill", -ENOENT);
+ acpi_add_table(ctx, ssdt);
+
+ return 0;
+}
+
+ACPI_WRITER(5ssdt, "SSDT", rpi_acpi_write_ssdt, 0);
+#endif
new file mode 100644
@@ -0,0 +1,111 @@
+/** @file
+ *
+ * [DSDT] SD controller/card definition (SDHC)
+ *
+ * Copyright (c) 2020, Pete Batard <pete@akeo.ie>
+ * Copyright (c) 2018, Andrey Warkentin <andrey.warkentin@gmail.com>
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#include <asm/arch/acpi/bcm2836_sdhost.h>
+#include <asm/arch/acpi/bcm2836_sdio.h>
+
+#include "acpitables.h"
+
+//
+// Note: UEFI can use either SDHost or Arasan. We expose both to the OS.
+//
+
+// ArasanSD 3.0 SD Host Controller. (brcm,bcm2835-sdhci)
+Device (SDC1)
+{
+ Name (_HID, "BCM2847")
+ Name (_CID, "BCM2847")
+ Name (_UID, 0x0)
+ Name (_CCA, 0x0)
+ Name (_S1D, 0x1)
+ Name (_S2D, 0x1)
+ Name (_S3D, 0x1)
+ Name (_S4D, 0x1)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, MMCHS1_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_MMCHS1_INTERRUPT }
+ })
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, MMCHS1_OFFSET)
+ Return (^RBUF)
+ }
+
+ // The standard CAPs registers on this controller
+ // appear to be 0, lets set some minimal defaults
+ // Since this cap doesn't indicate DMA capability
+ // we don't need a _DMA()
+ Name (_DSD, Package () {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package () {
+ Package () { "sdhci-caps", 0x0120fa81 },
+ }
+ })
+
+ //
+ // A child device that represents the
+ // sd card, which is marked as non-removable.
+ //
+ Device (SDMM)
+ {
+ Method (_ADR)
+ {
+ Return (0)
+ }
+ Method (_RMV) // Is removable
+ {
+ Return (0) // 0 - fixed
+ }
+ }
+}
+
+// Broadcom SDHost 2.0 SD Host Controller
+Device (SDC2)
+{
+ Name (_HID, "BCM2855")
+ Name (_CID, "BCM2855")
+ Name (_UID, 0x0)
+ Name (_CCA, 0x0)
+ Name (_S1D, 0x1)
+ Name (_S2D, 0x1)
+ Name (_S3D, 0x1)
+ Name (_S4D, 0x1)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, SDHOST_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_SDHOST_INTERRUPT }
+ })
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, SDHOST_OFFSET)
+ Return (^RBUF)
+ }
+
+ //
+ // A child device that represents the
+ // sd card, which is marked as non-removable.
+ //
+ Device (SDMM)
+ {
+ Method (_ADR)
+ {
+ Return (0)
+ }
+ Method (_RMV) // Is removable
+ {
+ Return (0) // 0 - fixed
+ }
+ }
+}
\ No newline at end of file
new file mode 100644
@@ -0,0 +1,208 @@
+/** @file
+ *
+ * [DSDT] Serial devices (UART).
+ *
+ * Copyright (c) 2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2020, Pete Batard <pete@akeo.ie>
+ * Copyright (c) 2018, Andrey Warkentin <andrey.warkentin@gmail.com>
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#include <asm/arch/acpi/bcm2836.h>
+
+#include "acpitables.h"
+
+// PL011 based UART.
+Device (URT0)
+{
+ Name (_HID, "BCM2837")
+ Name (_CID, "ARMH0011")
+ Name (_UID, 0x4)
+ Name (_CCA, 0x0)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_PL011_UART_LENGTH, RMEM)
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PL011_UART_INTERRUPT }
+ })
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_PL011_UART_OFFSET)
+ Return (^RBUF)
+ }
+
+ Name (CLCK, 48000000)
+
+ Name (_DSD, Package ()
+ {
+ ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package ()
+ {
+ Package (2) { "clock-frequency", CLCK },
+ }
+ })
+}
+
+//
+// UART Mini.
+//
+// This device is referenced in the DBG2 table, which will cause the system to
+// not start the driver when the debugger is enabled and to mark the device
+// with problem code 53 (CM_PROB_USED_BY_DEBUGGER).
+//
+
+Device (URTM)
+{
+ Name (_HID, "BCM2836")
+ Name (_CID, "BCM2836")
+ Name (_UID, 0x0)
+ Name (_CCA, 0x0)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ MEMORY32FIXED (ReadWrite, 0, BCM2836_MINI_UART_LENGTH, RMEM)
+ Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_MINI_UART_INTERRUPT }
+
+ })
+ Method (_CRS, 0x0, Serialized)
+ {
+ MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_MINI_UART_OFFSET)
+ Return (^RBUF)
+ }
+
+ //
+ // Mini Uart Clock Rate will be dynamically updated during boot
+ //
+ External (\_SB.URTM.MUCR, IntObj)
+
+ Name (_DSD, Package ()
+ {
+ ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package ()
+ {
+ Package (2) { "clock-frequency", MUCR },
+ }
+ })
+}
+
+//
+// Multifunction serial bus device to support Bluetooth function.
+//
+Device(BTH0)
+{
+ Name (_HID, "BCM2EA6")
+ Name (_CID, "BCM2EA6")
+
+ //
+ // UART In Use will be dynamically updated during boot
+ //
+ External (\_SB.BTH0.URIU, IntObj)
+
+ Method (_STA)
+ {
+ Return (0xf)
+ }
+
+ //
+ // Resource for URT0 (PL011)
+ //
+ Name (BTPL, ResourceTemplate ()
+ {
+ UARTSerialBus(
+ 115200, // InitialBaudRate: in BPS
+ , // BitsPerByte: default to 8 bits
+ , // StopBits: Defaults to one bit
+ 0x00, // LinesInUse: 8 1-bit flags to
+ // declare enabled control lines.
+ // Raspberry Pi does not exposed
+ // HW control signals -> not supported.
+ // Optional bits:
+ // - Bit 7 (0x80) Request To Send (RTS)
+ // - Bit 6 (0x40) Clear To Send (CTS)
+ // - Bit 5 (0x20) Data Terminal Ready (DTR)
+ // - Bit 4 (0x10) Data Set Ready (DSR)
+ // - Bit 3 (0x08) Ring Indicator (RI)
+ // - Bit 2 (0x04) Data Carrier Detect (DTD)
+ // - Bit 1 (0x02) Reserved. Must be 0.
+ // - Bit 0 (0x01) Reserved. Must be 0.
+ , // IsBigEndian:
+ // default to LittleEndian.
+ , // Parity: Defaults to no parity
+ , // FlowControl: Defaults to
+ // no flow control.
+ 16, // ReceiveBufferSize
+ 16, // TransmitBufferSize
+ "\\_SB.GDV0.URT0", // ResourceSource:
+ // UART bus controller name
+ , // ResourceSourceIndex: assumed to be 0
+ , // ResourceUsage: assumed to be
+ // ResourceConsumer
+ UAR0, // DescriptorName: creates name
+ // for offset of resource descriptor
+ ) // Vendor data
+ })
+
+ //
+ // Resource for URTM (miniUART)
+ //
+ Name (BTMN, ResourceTemplate ()
+ {
+ //
+ // BT UART: ResourceSource will be dynamically updated to
+ // either URT0 (PL011) or URTM (miniUART) during boot
+ //
+ UARTSerialBus(
+ 115200, // InitialBaudRate: in BPS
+ , // BitsPerByte: default to 8 bits
+ , // StopBits: Defaults to one bit
+ 0x00, // LinesInUse: 8 1-bit flags to
+ // declare enabled control lines.
+ // Raspberry Pi does not exposed
+ // HW control signals -> not supported.
+ // Optional bits:
+ // - Bit 7 (0x80) Request To Send (RTS)
+ // - Bit 6 (0x40) Clear To Send (CTS)
+ // - Bit 5 (0x20) Data Terminal Ready (DTR)
+ // - Bit 4 (0x10) Data Set Ready (DSR)
+ // - Bit 3 (0x08) Ring Indicator (RI)
+ // - Bit 2 (0x04) Data Carrier Detect (DTD)
+ // - Bit 1 (0x02) Reserved. Must be 0.
+ // - Bit 0 (0x01) Reserved. Must be 0.
+ , // IsBigEndian:
+ // default to LittleEndian.
+ , // Parity: Defaults to no parity
+ , // FlowControl: Defaults to
+ // no flow control.
+ 16, // ReceiveBufferSize
+ 16, // TransmitBufferSize
+ "\\_SB.GDV0.URTM", // ResourceSource:
+ // UART bus controller name
+ , // ResourceSourceIndex: assumed to be 0
+ , // ResourceUsage: assumed to be
+ // ResourceConsumer
+ UARM, // DescriptorName: creates name
+ // for offset of resource descriptor
+ ) // Vendor data
+ })
+
+ Method (_CRS, 0x0, Serialized)
+ {
+ if (URIU == 0)
+ {
+ //
+ // PL011 UART is configured for console output
+ // Return Mini UART for Bluetooth
+ //
+ return (^BTMN)
+ }
+ else
+ {
+ //
+ // Mini UART is configured for console output
+ // Return PL011 UART for Bluetooth
+ //
+ return (^BTPL)
+ }
+ }
+}