diff --git a/src/soc/intel/common/acpi/pch_pcr.asl b/src/soc/intel/common/acpi/pch_pcr.asl index 2a940a3160..d7991c4fd1 100644 --- a/src/soc/intel/common/acpi/pch_pcr.asl +++ b/src/soc/intel/common/acpi/pch_pcr.asl @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include +#include "pcrlib.asl" + +/* APIs to access P2SB inside PCH/SoC die */ /* * Calculate PCR register base at specified PID @@ -8,7 +10,7 @@ */ Method (PCRB, 1, NotSerialized) { - Return (CONFIG_PCR_BASE_ADDRESS + (Arg0 << PCR_PORTID_SHIFT)) + Return (GPCR(PCH_P2SB, Arg0)) } /* @@ -18,12 +20,7 @@ Method (PCRB, 1, NotSerialized) */ Method (PCRR, 2, Serialized) { - OperationRegion (PCRD, SystemMemory, PCRB (Arg0) + Arg1, 4) - Field (PCRD, DWordAcc, NoLock, Preserve) - { - DATA, 32 - } - Return (DATA) + Return (RPCR(PCH_P2SB, Arg0, Arg1)) } /* @@ -34,20 +31,7 @@ Method (PCRR, 2, Serialized) */ Method (PCRA, 3, Serialized) { - OperationRegion (PCRD, SystemMemory, PCRB (Arg0) + Arg1, 4) - Field (PCRD, DWordAcc, NoLock, Preserve) - { - DATA, 32 - } - DATA &= Arg2 - - /* - * After every write one needs to read an innocuous register - * to ensure the writes are completed for certain ports. This is done - * for all ports so that the callers don't need the per-port knowledge - * for each transaction. - */ - PCRR (Arg0, Arg1) + APCR(PCH_P2SB, Arg0, Arg1, Arg2) } /* @@ -58,18 +42,5 @@ Method (PCRA, 3, Serialized) */ Method (PCRO, 3, Serialized) { - OperationRegion (PCRD, SystemMemory, PCRB (Arg0) + Arg1, 4) - Field (PCRD, DWordAcc, NoLock, Preserve) - { - DATA, 32 - } - DATA |= Arg2 - - /* - * After every write one needs to read an innocuous register - * to ensure the writes are completed for certain ports. This is done - * for all ports so that the callers don't need the per-port knowledge - * for each transaction. - */ - PCRR (Arg0, Arg1) + OPCR(PCH_P2SB, Arg0, Arg1, Arg2) } diff --git a/src/soc/intel/common/acpi/pcrlib.asl b/src/soc/intel/common/acpi/pcrlib.asl new file mode 100644 index 0000000000..265118573d --- /dev/null +++ b/src/soc/intel/common/acpi/pcrlib.asl @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_INTEL_ACPI_PCR_LIB_ +#define _SOC_INTEL_ACPI_PCR_LIB_ + +/* Port Id lives in bits 23:16 and register offset lives in 15:0 of address. */ +#define PCR_PORTID_SHIFT 16 + +/* Die Index */ +#define PCH_P2SB 0x00 +/* TODO: Add index for P2SB which belongs to IOE Die" */ + +/* + * Get PCR register base for specified Die at given PID + * Arg0 - Die Index + * Arg1 - PCR Port ID + */ +Method (GPCR, 2, NotSerialized) +{ + if (Arg0 == PCH_P2SB) { + Local0 = CONFIG_PCR_BASE_ADDRESS; + } else { + Printf ("Invalid Die index (%o)\n", Arg0) + Return (0) + } + + Return (Local0 + (Arg1 << PCR_PORTID_SHIFT)) +} + +/* + * Read PCR register for specified Die at PID and offset + * Arg0 - Die Index + * Arg1 - PCR Port ID + * Arg2 - Register Offset + */ +Method (RPCR, 3, Serialized) +{ + OperationRegion (PCRD, SystemMemory, GPCR (Arg0, Arg1) + Arg2, 4) + Field (PCRD, DWordAcc, NoLock, Preserve) + { + DATA, 32 + } + Return (DATA) +} + +/* + * Perform PCR register AND for specified Die at PID and offset + * Arg0 - Die Index + * Arg1 - PCR Port ID + * Arg2 - Register Offset + * Arg3 - Value to AND + */ +Method (APCR, 4, Serialized) +{ + OperationRegion (PCRD, SystemMemory, GPCR (Arg0, Arg1) + Arg2, 4) + Field (PCRD, DWordAcc, NoLock, Preserve) + { + DATA, 32 + } + DATA &= Arg3 + + /* + * After every write one needs to read an innocuous register + * to ensure the writes are completed for certain ports. This is done + * for all ports so that the callers don't need the per-port knowledge + * for each transaction. + */ + RPCR (Arg0, Arg1, Arg2) +} + +/* + * Perform PCR register OR for specified Die at PID and offset + * Arg0 - Die Index + * Arg1 - PCR Port ID + * Arg2 - Register Offset + * Arg3 - Value to OR + */ +Method (OPCR, 4, Serialized) +{ + OperationRegion (PCRD, SystemMemory, GPCR (Arg0, Arg1) + Arg2, 4) + Field (PCRD, DWordAcc, NoLock, Preserve) + { + DATA, 32 + } + DATA |= Arg3 + + /* + * After every write one needs to read an innocuous register + * to ensure the writes are completed for certain ports. This is done + * for all ports so that the callers don't need the per-port knowledge + * for each transaction. + */ + RPCR (Arg0, Arg1, Arg2) +} + +#endif /* _SOC_INTEL_ACPI_PCR_LIB_ */