| /* SPDX-License-Identifier: GPL-2.0-only */ |
| |
| #include <amdblocks/alib.h> |
| #include <arch/vga.h> |
| |
| External(\_SB.ALIB, MethodObj) |
| |
| /* System Bus */ |
| /* _SB.PCI0 */ |
| |
| /* Describe the Southbridge devices */ |
| |
| /* 0:14.0 - SMBUS */ |
| Device(SBUS) { |
| Name(_ADR, 0x00140000) |
| } /* end SBUS */ |
| |
| #include "usb.asl" |
| |
| /* 0:14.2 - I2S Audio */ |
| |
| /* 0:14.3 - LPC */ |
| #include <soc/amd/common/acpi/lpc.asl> |
| |
| /* 0:14.7 - SD Controller */ |
| Device(SDCN) { |
| Name(_ADR, 0x00140007) |
| |
| Method(_PS0) { |
| FDDC(24, 0) |
| } |
| Method(_PS3) { |
| FDDC(24, 3) |
| } |
| Method(_PSC) { |
| Return(SDTD) |
| } |
| } /* end SDCN */ |
| |
| Name(CRES, ResourceTemplate() { |
| /* Set the Bus number and Secondary Bus number for the PCI0 device |
| * The Secondary bus range for PCI0 lets the system |
| * know what bus values are allowed on the downstream |
| * side of this PCI bus if there is a PCI-PCI bridge. |
| * PCI buses can have 256 secondary buses which |
| * range from [0-0xFF] but they do not need to be |
| * sequential. |
| */ |
| WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, |
| 0x0000, /* address granularity */ |
| 0x0000, /* range minimum */ |
| 0x00ff, /* range maximum */ |
| 0x0000, /* translation */ |
| 0x0100, /* length */ |
| ,, PSB0) /* ResourceSourceIndex, ResourceSource, DescriptorName */ |
| |
| IO(Decode16, 0x0cf8, 0x0cf8, 1, 8) |
| |
| WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, |
| 0x0000, /* address granularity */ |
| 0x0000, /* range minimum */ |
| 0x0cf7, /* range maximum */ |
| 0x0000, /* translation */ |
| 0x0cf8 /* length */ |
| ) |
| |
| WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, |
| 0x0000, /* address granularity */ |
| 0x0d00, /* range minimum */ |
| 0xffff, /* range maximum */ |
| 0x0000, /* translation */ |
| 0xf300 /* length */ |
| ) |
| |
| Memory32Fixed(READONLY, VGA_MMIO_BASE, VGA_MMIO_SIZE, VGAM) /* VGA memory space */ |
| Memory32Fixed(READONLY, 0x000c0000, 0x00020000, EMM1) /* Assume C0000-E0000 empty */ |
| |
| /* memory space for PCI BARs below 4GB */ |
| Memory32Fixed(ReadOnly, 0x00000000, 0x00000000, MMIO) |
| }) /* End Name(_SB.PCI0.CRES) */ |
| |
| Method(_CRS, 0) { |
| /* DBGO("\\_SB\\PCI0\\_CRS\n") */ |
| CreateDWordField(CRES, ^MMIO._BAS, MM1B) |
| CreateDWordField(CRES, ^MMIO._LEN, MM1L) |
| |
| /* Declare memory between TOM1 and MMCONF as available for PCI MMIO. */ |
| MM1B = TOM1 |
| Local0 = CONFIG_ECAM_MMCONF_BASE_ADDRESS |
| Local0 -= TOM1 |
| MM1L = Local0 |
| |
| CreateWordField(CRES, ^PSB0._MAX, BMAX) |
| CreateWordField(CRES, ^PSB0._LEN, BLEN) |
| BMAX = CONFIG_ECAM_MMCONF_BUS_NUMBER - 1 |
| BLEN = CONFIG_ECAM_MMCONF_BUS_NUMBER |
| |
| Return (CRES) /* note to change the Name buffer */ |
| } /* end of Method(_SB.PCI0._CRS) */ |
| |
| /* |
| * |
| * FIRST METHOD CALLED UPON BOOT |
| * |
| * 1. If debugging, print current OS and ACPI interpreter. |
| * 2. Get PCI Interrupt routing from ACPI VSM, this |
| * value is based on user choice in BIOS setup. |
| */ |
| Method(_INI, 0, Serialized) { |
| /* DBGO("\\_SB\\_INI\n") */ |
| /* DBGO(" DSDT.ASL code from ") */ |
| /* DBGO(__DATE__) */ |
| /* DBGO(" ") */ |
| /* DBGO(__TIME__) */ |
| /* DBGO("\n Sleep states supported: ") */ |
| /* DBGO("\n") */ |
| /* DBGO(" \\_OS=") */ |
| /* DBGO(\_OS) */ |
| /* DBGO("\n \\_REV=") */ |
| /* DBGO(\_REV) */ |
| /* DBGO("\n") */ |
| |
| /* Send ALIB Function 1 the AC/DC state */ |
| Name(F1BF, Buffer(0x03){}) |
| CreateWordField(F1BF, 0, F1SZ) |
| CreateByteField(F1BF, 2, F1DA) |
| |
| F1SZ = 3 |
| F1DA= \PWRS |
| |
| \_SB.ALIB(ALIB_FUNCTION_REPORT_AC_DC_STATE, F1BF) |
| |
| } /* End Method(_SB._INI) */ |
| |
| OperationRegion(SMIC, SystemMemory, 0xfed80000, 0x80000) |
| Field( SMIC, ByteAcc, NoLock, Preserve) { |
| /* MISC registers */ |
| offset (0x03ee), |
| U3PS, 2, /* Usb3PowerSel */ |
| |
| offset (0x0e28), |
| ,29 , |
| SARP, 1, /* Sata Ref Clock Powerdown */ |
| U2RP, 1, /* Usb2 Ref Clock Powerdown */ |
| U3RP, 1, /* Usb3 Ref Clock Powerdown */ |
| |
| /* XHCI_PM registers */ |
| offset (0x1c00), |
| , 1, |
| ,6, |
| U3PY, 1, |
| , 7, |
| UD3P, 1, /* bit 15 */ |
| U3PR, 1, /* bit 16 */ |
| , 11, |
| FWLM, 1, /* FirmWare Load Mode */ |
| FPLS, 1, /* Fw PreLoad Start */ |
| FPLC, 1, /* Fw PreLoad Complete */ |
| |
| offset (0x1c04), |
| UA04, 16, |
| , 15, |
| ROAM, 1, /* 1= ROM 0=RAM */ |
| |
| offset (0x1c08), |
| UA08, 32, |
| |
| /* AOAC Registers */ |
| offset (0x1e4a), /* I2C0 D3 Control */ |
| I0TD, 2, |
| , 1, |
| I0PD, 1, |
| offset (0x1e4b), /* I2C0 D3 State */ |
| I0DS, 3, |
| |
| offset (0x1e4c), /* I2C1 D3 Control */ |
| I1TD, 2, |
| , 1, |
| I1PD, 1, |
| offset (0x1e4d), /* I2C1 D3 State */ |
| I1DS, 3, |
| |
| offset (0x1e4e), /* I2C2 D3 Control */ |
| I2TD, 2, |
| , 1, |
| I2PD, 1, |
| offset (0x1e4f), /* I2C2 D3 State */ |
| I2DS, 3, |
| |
| offset (0x1e50), /* I2C3 D3 Control */ |
| I3TD, 2, |
| , 1, |
| I3PD, 1, |
| offset (0x1e51), /* I2C3 D3 State */ |
| I3DS, 3, |
| |
| offset (0x1e56), /* UART0 D3 Control */ |
| U0TD, 2, |
| , 1, |
| U0PD, 1, |
| offset (0x1e57), /* UART0 D3 State */ |
| U0DS, 3, |
| |
| offset (0x1e58), /* UART1 D3 Control */ |
| U1TD, 2, |
| , 1, |
| U1PD, 1, |
| offset (0x1e59), /* UART1 D3 State */ |
| U1DS, 3, |
| |
| offset (0x1e5e), /* SATA D3 Control */ |
| SATD, 2, |
| , 1, |
| SAPD, 1, |
| offset (0x1e5f), /* SATA D3 State */ |
| SADS, 3, |
| |
| offset (0x1e64), /* USB2 D3 Control */ |
| U2TD, 2, |
| , 1, |
| U2PD, 1, |
| offset (0x1e65), /* USB2 D3 State */ |
| U2DS, 3, |
| |
| offset (0x1e6e), /* USB3 D3 Control */ |
| U3TD, 2, |
| , 1, |
| U3PD, 1, |
| offset (0x1e6f), /* USB3 D3 State */ |
| U3DS, 3, |
| |
| offset (0x1e70), /* SD D3 Control */ |
| SDTD, 2, |
| , 1, |
| SDPD, 1, |
| , 1, |
| , 1, |
| SDRT, 1, |
| SDSC, 1, |
| |
| offset (0x1e71), /* SD D3 State */ |
| SDDS, 3, |
| |
| offset (0x1e80), /* Shadow Register Request */ |
| , 15, |
| RQ15, 1, |
| , 2, |
| RQ18, 1, |
| , 4, |
| RQ23, 1, |
| RQ24, 1, |
| , 5, |
| RQTY, 1, |
| offset (0x1e84), /* Shadow Register Status */ |
| , 15, |
| SASR, 1, /* SATA 15 Shadow Reg Request Status Register */ |
| , 2, |
| U2SR, 1, /* USB2 18 Shadow Reg Request Status Register */ |
| , 4, |
| U3SR, 1, /* USB3 23 Shadow Reg Request Status Register */ |
| SDSR, 1, /* SD 24 Shadow Reg Request Status Register */ |
| |
| offset (0x1ea0), /* PwrGood Control */ |
| PG1A, 1, |
| PG2_, 1, |
| ,1, |
| U3PG, 1, /* Usb3 Power Good BIT3 */ |
| |
| offset (0x1ea3), /* PwrGood Control b[31:24] */ |
| PGA3, 8 , |
| } |
| |
| Field(PCFG, DwordAcc, NoLock, Preserve) |
| { |
| /* XHCI */ |
| Offset(0x00080010), /* Base address */ |
| XHBA, 32, |
| Offset(0x0008002c), /* Subsystem ID / Vendor ID */ |
| XH2C, 32, |
| |
| Offset(0x00080048), /* Indirect PCI Index Register */ |
| IDEX, 32, |
| DATA, 32, |
| Offset(0x00080054), /* PME Control / Status */ |
| U_PS, 2, |
| |
| /* EHCI */ |
| Offset(0x00090004), /* Control */ |
| , 1, |
| EHME, 1, |
| Offset(0x00090010), /* Base address */ |
| EHBA, 32, |
| Offset(0x0009002c), /* Subsystem ID / Vendor ID */ |
| EH2C, 32, |
| Offset(0x00090054), /* EHCI Spare 1 */ |
| EH54, 8, |
| Offset(0x00090064), /* Misc Control 2 */ |
| EH64, 8, |
| |
| Offset(0x000900c4), /* PME Control / Status */ |
| E_PS, 2, |
| |
| /* LPC Bridge */ |
| Offset(0x000a30cb), /* ClientRomProtect[31:24] */ |
| , 7, |
| AUSS, 1, /* AutoSizeStart */ |
| } |
| |
| /* |
| * Arg0:device: |
| * 5=I2C0, 6=I2C1, 7=I2C2, 8=I2C3, 11=UART0, 12=UART1, |
| * 15=SATA, 18=EHCI, 23=xHCI, 24=SD |
| * Arg1:D-state |
| */ |
| Mutex (FDAS, 0) /* FCH Device AOAC Semophore */ |
| Method(FDDC, 2, Serialized) |
| { |
| Acquire(FDAS, 0xffff) |
| |
| if (Arg1 == 0) { |
| Switch(ToInteger(Arg0)) { |
| Case(Package() {5, 15, 24}) { |
| PG1A = 1 |
| } |
| Case(Package() {6, 7, 8, 11, 12, 18}) { |
| PG2_ = 1 |
| } |
| } |
| /* put device into D0 */ |
| Switch(ToInteger(Arg0)) |
| { |
| Case(5) { |
| I0TD = 0x00 |
| I0PD = 1 |
| Local0 = I0DS |
| while(Local0 != 0x7) { |
| Local0 = I0DS |
| } |
| } |
| Case(6) { |
| I1TD = 0x00 |
| I1PD = 1 |
| Local0 = I1DS |
| while(Local0 != 0x7) { |
| Local0 = I1DS |
| } |
| } |
| Case(7) { |
| I2TD = 0x00 |
| I2PD = 1 |
| Local0 = I2DS |
| while(Local0 != 0x7) { |
| Local0 = I2DS |
| } |
| } |
| Case(8) { |
| I3TD = 0x00 |
| I3PD = 1 |
| Local0 = I3DS |
| while(Local0 != 0x7) { |
| Local0 = I3DS |
| } |
| } |
| Case(11) { |
| U0TD = 0x00 |
| U0PD = 1 |
| Local0 = U0DS |
| while(Local0 != 0x7) { |
| Local0 = U0DS |
| } |
| } |
| Case(12) { |
| U1TD = 0x00 |
| U1PD = 1 |
| Local0 = U1DS |
| while(Local0 != 0x7) { |
| Local0 = U1DS |
| } |
| } |
| /* todo Case(15) { STD0()} */ /* SATA */ |
| Case(18) { U2D0()} /* EHCI */ |
| Case(23) { U3D0()} /* XHCI */ |
| Case(24) { /* SD */ |
| SDTD = 0x00 |
| SDPD = 1 |
| Local0 = SDDS |
| while(Local0 != 0x7) { |
| Local0 = SDDS |
| } |
| } |
| } |
| } else { |
| /* put device into D3cold */ |
| Switch(ToInteger(Arg0)) |
| { |
| Case(5) { |
| I0PD = 0 |
| Local0 = I0DS |
| while(Local0 != 0x0) { |
| Local0 = I0DS |
| } |
| I0TD = 0x03 |
| } |
| Case(6) { |
| I1PD = 0 |
| Local0 = I1DS |
| while(Local0 != 0x0) { |
| Local0 = I1DS |
| } |
| I1TD = 0x03 |
| } |
| Case(7) { |
| I2PD = 0 |
| Local0 = I2DS |
| while(Local0 != 0x0) { |
| Local0 = I2DS |
| } |
| I2TD = 0x03 |
| } |
| Case(8) { |
| I3PD = 0 |
| Local0 = I3DS |
| while(Local0 != 0x0) { |
| Local0 = I3DS |
| } |
| I3TD = 0x03 |
| } |
| Case(11) { |
| U0PD = 0 |
| Local0 = U0DS |
| while(Local0 != 0x0) { |
| Local0 = U0DS |
| } |
| U0TD = 0x03 |
| } |
| Case(12) { |
| U1PD = 0 |
| Local0 = U1DS |
| while(Local0 != 0x0) { |
| Local0 = U1DS |
| } |
| U1TD = 0x03 |
| } |
| /* todo Case(15) { STD3()} */ /* SATA */ |
| Case(18) { U2D3()} /* EHCI */ |
| Case(23) { U3D3()} /* XHCI */ |
| Case(24) { /* SD */ |
| SDPD = 0 |
| Local0 = SDDS |
| while(Local0 != 0x0) { |
| Local0 = SDDS |
| } |
| SDTD = 0x03 |
| } |
| } |
| /* Turn off Power */ |
| if (I0TD == 3) { |
| if (SATD == 3) { |
| if (SDTD == 3) { PG1A = 0 } |
| } |
| } |
| if (I1TD == 3) { |
| if (I2TD == 3) { |
| if (I3TD == 3) { |
| if (U0TD == 3) { |
| if (U1TD == 3) { |
| if (U2TD == 3) { |
| PG2_ = 0 |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| Release(FDAS) |
| } |
| |
| Method(FPTS,0, Serialized) /* FCH _PTS */ |
| { |
| if (\XHCE == one) { |
| if (U3TD != 0x03) { |
| FDDC(23, 3) |
| } |
| } |
| if (U2TD != 0x03) { |
| FDDC(18, 3) |
| } |
| } |
| |
| Method(FWAK,0, Serialized) /* FCH _WAK */ |
| { |
| if (\XHCE == one) { |
| if (U3TD == 0x03) { |
| FDDC(23, 0) |
| } |
| } |
| if (U2TD == 0x03) { |
| FDDC(18, 0) |
| } |
| if (\UT0E == zero) { |
| if (U0TD != 0x03) { |
| FDDC(11, 3) |
| } |
| } |
| if (\UT1E == zero) { |
| if (U1TD != 0x03) { |
| FDDC(12, 3) |
| } |
| } |
| if (\IC0E == zero) { |
| if (I0TD != 0x03) { |
| FDDC(5, 3) |
| } |
| } |
| if (\IC1E == zero) { |
| if (I1TD != 0x03) { |
| FDDC(6, 3) |
| } |
| } |
| if (\IC2E == zero) { |
| if (I2TD != 0x03) { |
| FDDC(7, 3) |
| } |
| } |
| if (\IC3E == zero) { |
| if (I3TD != 0x03) { |
| FDDC(8, 3) |
| } |
| } |
| } |
| |
| /* |
| * Helper for setting a bit in AOACxA0 PwrGood Control |
| * Arg0: bit to set or clear |
| * Arg1: 0 = clear bit[Arg0], non-zero = set bit[Arg0] |
| */ |
| Method(PWGC,2, Serialized) |
| { |
| Local0 = PGA3 & 0xdf /* do SwUsb3SlpShutdown below */ |
| if (Arg1) { |
| Local0 |= Arg0 |
| } else { |
| Local1 = ~Arg0 |
| Local0 &= Local1 |
| } |
| PGA3 = Local0 |
| if (Arg0 == 0x20) { /* if SwUsb3SlpShutdown */ |
| Local0 = PGA3 |
| Local0 &= Arg0 |
| while(!Local0) { /* wait SwUsb3SlpShutdown to complete */ |
| Local0 = PGA3 |
| Local0 &= Arg0 |
| } |
| } |
| } |