soc/amd/stoneyridge: Generate SATA ACPI registers at runtime
Convert SATA controller ACPI OperationRegion and Field definitions from static ASL code to runtime-generated acpigen code. This allows the SATA registers (STB5, SB5, and port fields P0ER-P3PR) to be conditionally included in ACPI tables only when the SATA controller (device 00:11.0) is enabled in the devicetree. Including them unconditionally when the SATA PCI device is disabled causes Windows to BSOD (ACPI BIOS ERROR), since the OpRegion references a non-existent device. Changes: - Move SATA OperationRegion generation to sata.c using acpigen APIs - Remove static SATA fields from acpi/pci_int.asl - Add stoneyridge_sata_ops with acpi_fill_ssdt callback - Update chipset_st.cb and chipset_cz.cb to use stoneyridge_sata_ops - Remove Kconfig for SoC common SATA code, since no longer used This reduces ACPI table size when SATA is disabled and properly scopes SATA registers to the SATA device. TEST=boot Win11 on google/liara without a BSOD Change-Id: I6e7a9a60e3622368eac83c36efd384c8d92c2b05 Signed-off-by: Matt DeVillier <matt.devillier@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/89855 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Paul Menzel <paulepanter@mailbox.org> Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com>
This commit is contained in:
parent
d62653749c
commit
9dc35142ac
5 changed files with 227 additions and 76 deletions
|
|
@ -36,7 +36,6 @@ config SOC_AMD_STONEYRIDGE
|
|||
select SOC_AMD_COMMON_BLOCK_PCI
|
||||
select SOC_AMD_COMMON_BLOCK_PM
|
||||
select SOC_AMD_COMMON_BLOCK_PSP_GEN1
|
||||
select SOC_AMD_COMMON_BLOCK_SATA
|
||||
select SOC_AMD_COMMON_BLOCK_SMBUS
|
||||
select SOC_AMD_COMMON_BLOCK_SMI
|
||||
select SOC_AMD_COMMON_BLOCK_SMM
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
* ((bus number + 1) * ((device number * 8) * 4096)) + register offset
|
||||
* The 8 comes from 8 functions per device, and 4096 bytes per function config space
|
||||
*/
|
||||
Offset(0x00088024), /* Byte offset to SATA register 24h - Bus 0, Device 17, Function 0 */
|
||||
STB5, 32,
|
||||
Offset(0x00098042), /* Byte offset to OHCI0 register 42h - Bus 0, Device 19, Function 0 */
|
||||
PT0D, 1,
|
||||
PT1D, 1,
|
||||
|
|
@ -30,76 +28,12 @@
|
|||
P92E, 1, /* Port92 decode enable */
|
||||
}
|
||||
|
||||
OperationRegion(SB5, SystemMemory, STB5, 0x1000)
|
||||
Field(SB5, AnyAcc, NoLock, Preserve){
|
||||
/* Port 0 */
|
||||
Offset(0x120), /* Port 0 Task file status */
|
||||
P0ER, 1,
|
||||
, 2,
|
||||
P0DQ, 1,
|
||||
, 3,
|
||||
P0BY, 1,
|
||||
Offset(0x128), /* Port 0 Serial ATA status */
|
||||
P0DD, 4,
|
||||
, 4,
|
||||
P0IS, 4,
|
||||
Offset(0x12c), /* Port 0 Serial ATA control */
|
||||
P0DI, 4,
|
||||
Offset(0x130), /* Port 0 Serial ATA error */
|
||||
, 16,
|
||||
P0PR, 1,
|
||||
|
||||
/* Port 1 */
|
||||
offset(0x1a0), /* Port 1 Task file status */
|
||||
P1ER, 1,
|
||||
, 2,
|
||||
P1DQ, 1,
|
||||
, 3,
|
||||
P1BY, 1,
|
||||
Offset(0x1a8), /* Port 1 Serial ATA status */
|
||||
P1DD, 4,
|
||||
, 4,
|
||||
P1IS, 4,
|
||||
Offset(0x1ac), /* Port 1 Serial ATA control */
|
||||
P1DI, 4,
|
||||
Offset(0x1b0), /* Port 1 Serial ATA error */
|
||||
, 16,
|
||||
P1PR, 1,
|
||||
|
||||
/* Port 2 */
|
||||
Offset(0x220), /* Port 2 Task file status */
|
||||
P2ER, 1,
|
||||
, 2,
|
||||
P2DQ, 1,
|
||||
, 3,
|
||||
P2BY, 1,
|
||||
Offset(0x228), /* Port 2 Serial ATA status */
|
||||
P2DD, 4,
|
||||
, 4,
|
||||
P2IS, 4,
|
||||
Offset(0x22c), /* Port 2 Serial ATA control */
|
||||
P2DI, 4,
|
||||
Offset(0x230), /* Port 2 Serial ATA error */
|
||||
, 16,
|
||||
P2PR, 1,
|
||||
|
||||
/* Port 3 */
|
||||
Offset(0x2a0), /* Port 3 Task file status */
|
||||
P3ER, 1,
|
||||
, 2,
|
||||
P3DQ, 1,
|
||||
, 3,
|
||||
P3BY, 1,
|
||||
Offset(0x2a8), /* Port 3 Serial ATA status */
|
||||
P3DD, 4,
|
||||
, 4,
|
||||
P3IS, 4,
|
||||
Offset(0x2aC), /* Port 3 Serial ATA control */
|
||||
P3DI, 4,
|
||||
Offset(0x2b0), /* Port 3 Serial ATA error */
|
||||
, 16,
|
||||
P3PR, 1,
|
||||
}
|
||||
/*
|
||||
* SATA OperationRegion (STB5, SB5) and port Fields (P0ER, P0DQ, etc.)
|
||||
* are now generated at runtime via acpigen in acpi_sata.c
|
||||
* This allows the SATA registers to only be included when the SATA
|
||||
* controller (device 00:11.0) is enabled in the devicetree.
|
||||
*/
|
||||
|
||||
Name(IRQB, ResourceTemplate(){
|
||||
IRQ(Level,ActiveLow,Shared){15}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ chip soc/amd/stoneyridge
|
|||
device pci 09.0 alias hda_bridge off end # host audio bridge
|
||||
device pci 09.2 alias hda off end # main HD Audio Controller
|
||||
device pci 10.0 alias xhci off ops stoneyridge_usb_ops end
|
||||
device pci 11.0 alias sata off ops amd_sata_ops end
|
||||
device pci 11.0 alias sata off ops stoneyridge_sata_ops end
|
||||
device pci 12.0 alias ehci off ops stoneyridge_usb_ops end
|
||||
device pci 14.0 alias smbus on ops amd_smbus_ops end # primary FCH function
|
||||
device pci 14.3 alias lpc_bridge on ops amd_lpc_ops end
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ chip soc/amd/stoneyridge
|
|||
device pci 09.0 alias hda_bridge off end # host audio bridge
|
||||
device pci 09.2 alias hda off end # main HD Audio Controller
|
||||
device pci 10.0 alias xhci off ops stoneyridge_usb_ops end
|
||||
device pci 11.0 alias sata off ops amd_sata_ops end
|
||||
device pci 11.0 alias sata off ops stoneyridge_sata_ops end
|
||||
device pci 12.0 alias ehci off ops stoneyridge_usb_ops end
|
||||
device pci 14.0 alias smbus on ops amd_smbus_ops end # primary FCH function
|
||||
device pci 14.3 alias lpc_bridge on ops amd_lpc_ops end
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <acpi/acpi_device.h>
|
||||
#include <acpi/acpigen.h>
|
||||
#include <amdblocks/sata.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <amdblocks/sata.h>
|
||||
#include <soc/southbridge.h>
|
||||
|
||||
void soc_enable_sata_features(struct device *dev)
|
||||
|
|
@ -30,4 +33,219 @@ void soc_enable_sata_features(struct device *dev)
|
|||
temp = pci_read_config32(dev, SATA_MISC_CONTROL_REG);
|
||||
temp &= ~SATA_MISC_SUBCLASS_WREN;
|
||||
pci_write_config32(dev, SATA_MISC_CONTROL_REG, temp);
|
||||
}
|
||||
|
||||
#if CONFIG(HAVE_ACPI_TABLES)
|
||||
|
||||
/*
|
||||
* Generate ACPI SATA OperationRegion and Fields for port status
|
||||
* This is only generated if the SATA device (00:11.0) is enabled
|
||||
*/
|
||||
static void sata_acpi_fill_ssdt(const struct device *dev)
|
||||
{
|
||||
const char *scope;
|
||||
|
||||
if (!dev->enabled)
|
||||
return;
|
||||
|
||||
/* First generate the standard PCI device info */
|
||||
acpi_device_write_pci_dev(dev);
|
||||
|
||||
/* Get the scope for the SATA device */
|
||||
scope = acpi_device_path(dev);
|
||||
if (!scope)
|
||||
return;
|
||||
|
||||
acpigen_write_scope(scope);
|
||||
|
||||
/*
|
||||
* Generate Field in PCFG OperationRegion for SATA BAR5 register
|
||||
* PCFG is the PCI config space OperationRegion defined elsewhere
|
||||
*
|
||||
* Field(PCFG, ByteAcc, NoLock, Preserve) {
|
||||
* Offset(0x00088024),
|
||||
* STB5, 32,
|
||||
* }
|
||||
*
|
||||
*/
|
||||
struct fieldlist sata_pcfg_field[] = {
|
||||
FIELDLIST_OFFSET(0x00088024), /* SATA device register 24h */
|
||||
FIELDLIST_NAMESTR("STB5", 32), /* SATA BAR5 (ABAR) */
|
||||
};
|
||||
acpigen_write_field("PCFG", sata_pcfg_field, ARRAY_SIZE(sata_pcfg_field),
|
||||
FIELD_BYTEACC | FIELD_NOLOCK | FIELD_PRESERVE);
|
||||
|
||||
/*
|
||||
* Generate OperationRegion for SATA AHCI memory space
|
||||
* This maps to the BAR5 (ABAR) memory region:
|
||||
*
|
||||
* OperationRegion(SB5, SystemMemory, STB5, 0x1000)
|
||||
*
|
||||
*/
|
||||
acpigen_emit_ext_op(OPREGION_OP);
|
||||
acpigen_emit_namestring("SB5");
|
||||
acpigen_emit_byte(SYSTEMMEMORY);
|
||||
acpigen_emit_namestring("STB5"); /* Reference to the STB5 field defined above */
|
||||
acpigen_write_integer(0x1000);
|
||||
|
||||
/*
|
||||
* Generate Field in SB5 OperationRegion for SATA port registers
|
||||
* These fields allow access to AHCI port status registers:
|
||||
*
|
||||
* Field(SB5, AnyAcc, NoLock, Preserve) {
|
||||
* Offset(0x120),
|
||||
* P0ER, 1,
|
||||
* , 2,
|
||||
* P0DQ, 1,
|
||||
* , 3,
|
||||
* P0BY, 1,
|
||||
* Offset(0x128),
|
||||
* P0DD, 4,
|
||||
* , 4,
|
||||
* P0IS, 4,
|
||||
* Offset(0x12c),
|
||||
* P0DI, 4,
|
||||
* Offset(0x130),
|
||||
* , 16,
|
||||
* P0PR, 1,
|
||||
* Offset(0x1a0),
|
||||
* P1ER, 1,
|
||||
* , 2,
|
||||
* P1DQ, 1,
|
||||
* , 3,
|
||||
* P1BY, 1,
|
||||
* Offset(0x1a8),
|
||||
* P1DD, 4,
|
||||
* , 4,
|
||||
* P1IS, 4,
|
||||
* Offset(0x1ac),
|
||||
* P1DI, 4,
|
||||
* Offset(0x1b0),
|
||||
* , 16,
|
||||
* P1PR, 1,
|
||||
* Offset(0x220),
|
||||
* P2ER, 1,
|
||||
* , 2,
|
||||
* P2DQ, 1,
|
||||
* , 3,
|
||||
* P2BY, 1,
|
||||
* Offset(0x228),
|
||||
* P2DD, 4,
|
||||
* , 4,
|
||||
* P2IS, 4,
|
||||
* Offset(0x22c),
|
||||
* P2DI, 4,
|
||||
* Offset(0x230),
|
||||
* , 16,
|
||||
* P2PR, 1,
|
||||
* Offset(0x2a0),
|
||||
* P3ER, 1,
|
||||
* , 2,
|
||||
* P3DQ, 1,
|
||||
* , 3,
|
||||
* P3BY, 1,
|
||||
* Offset(0x2a8),
|
||||
* P3DD, 4,
|
||||
* , 4,
|
||||
* P3IS, 4,
|
||||
* Offset(0x2ac),
|
||||
* P3DI, 4,
|
||||
* Offset(0x2b0),
|
||||
* , 16,
|
||||
* P3PR, 1,
|
||||
* }
|
||||
*
|
||||
*/
|
||||
struct fieldlist sata_port_fields[] = {
|
||||
/* Port 0 - offset 0x120 */
|
||||
FIELDLIST_OFFSET(0x120),
|
||||
FIELDLIST_NAMESTR("P0ER", 1), /* Error bit */
|
||||
FIELDLIST_RESERVED(2),
|
||||
FIELDLIST_NAMESTR("P0DQ", 1), /* Data request */
|
||||
FIELDLIST_RESERVED(3),
|
||||
FIELDLIST_NAMESTR("P0BY", 1), /* Busy */
|
||||
FIELDLIST_OFFSET(0x128),
|
||||
FIELDLIST_NAMESTR("P0DD", 4), /* Device detection */
|
||||
FIELDLIST_RESERVED(4),
|
||||
FIELDLIST_NAMESTR("P0IS", 4), /* Interface speed */
|
||||
FIELDLIST_OFFSET(0x12c),
|
||||
FIELDLIST_NAMESTR("P0DI", 4), /* Device idle */
|
||||
FIELDLIST_OFFSET(0x130),
|
||||
FIELDLIST_RESERVED(16),
|
||||
FIELDLIST_NAMESTR("P0PR", 1), /* Port ready */
|
||||
|
||||
/* Port 1 - offset 0x1a0 */
|
||||
FIELDLIST_OFFSET(0x1a0),
|
||||
FIELDLIST_NAMESTR("P1ER", 1),
|
||||
FIELDLIST_RESERVED(2),
|
||||
FIELDLIST_NAMESTR("P1DQ", 1),
|
||||
FIELDLIST_RESERVED(3),
|
||||
FIELDLIST_NAMESTR("P1BY", 1),
|
||||
FIELDLIST_OFFSET(0x1a8),
|
||||
FIELDLIST_NAMESTR("P1DD", 4),
|
||||
FIELDLIST_RESERVED(4),
|
||||
FIELDLIST_NAMESTR("P1IS", 4),
|
||||
FIELDLIST_OFFSET(0x1ac),
|
||||
FIELDLIST_NAMESTR("P1DI", 4),
|
||||
FIELDLIST_OFFSET(0x1b0),
|
||||
FIELDLIST_RESERVED(16),
|
||||
FIELDLIST_NAMESTR("P1PR", 1),
|
||||
|
||||
/* Port 2 - offset 0x220 */
|
||||
FIELDLIST_OFFSET(0x220),
|
||||
FIELDLIST_NAMESTR("P2ER", 1),
|
||||
FIELDLIST_RESERVED(2),
|
||||
FIELDLIST_NAMESTR("P2DQ", 1),
|
||||
FIELDLIST_RESERVED(3),
|
||||
FIELDLIST_NAMESTR("P2BY", 1),
|
||||
FIELDLIST_OFFSET(0x228),
|
||||
FIELDLIST_NAMESTR("P2DD", 4),
|
||||
FIELDLIST_RESERVED(4),
|
||||
FIELDLIST_NAMESTR("P2IS", 4),
|
||||
FIELDLIST_OFFSET(0x22c),
|
||||
FIELDLIST_NAMESTR("P2DI", 4),
|
||||
FIELDLIST_OFFSET(0x230),
|
||||
FIELDLIST_RESERVED(16),
|
||||
FIELDLIST_NAMESTR("P2PR", 1),
|
||||
|
||||
/* Port 3 - offset 0x2a0 */
|
||||
FIELDLIST_OFFSET(0x2a0),
|
||||
FIELDLIST_NAMESTR("P3ER", 1),
|
||||
FIELDLIST_RESERVED(2),
|
||||
FIELDLIST_NAMESTR("P3DQ", 1),
|
||||
FIELDLIST_RESERVED(3),
|
||||
FIELDLIST_NAMESTR("P3BY", 1),
|
||||
FIELDLIST_OFFSET(0x2a8),
|
||||
FIELDLIST_NAMESTR("P3DD", 4),
|
||||
FIELDLIST_RESERVED(4),
|
||||
FIELDLIST_NAMESTR("P3IS", 4),
|
||||
FIELDLIST_OFFSET(0x2ac),
|
||||
FIELDLIST_NAMESTR("P3DI", 4),
|
||||
FIELDLIST_OFFSET(0x2b0),
|
||||
FIELDLIST_RESERVED(16),
|
||||
FIELDLIST_NAMESTR("P3PR", 1),
|
||||
};
|
||||
acpigen_write_field("SB5", sata_port_fields, ARRAY_SIZE(sata_port_fields),
|
||||
FIELD_ANYACC | FIELD_NOLOCK | FIELD_PRESERVE);
|
||||
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
|
||||
static const char *sata_acpi_name(const struct device *dev)
|
||||
{
|
||||
return "STCR";
|
||||
}
|
||||
|
||||
#endif /* CONFIG(HAVE_ACPI_TABLES) */
|
||||
|
||||
struct device_operations stoneyridge_sata_ops = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = soc_enable_sata_features,
|
||||
.ops_pci = &pci_dev_ops_pci,
|
||||
#if CONFIG(HAVE_ACPI_TABLES)
|
||||
.acpi_name = sata_acpi_name,
|
||||
.acpi_fill_ssdt = sata_acpi_fill_ssdt,
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue