diff options
Diffstat (limited to 'src/soc')
-rw-r--r-- | src/soc/intel/skylake/include/soc/pcr.h | 5 | ||||
-rw-r--r-- | src/soc/intel/skylake/pcr.c | 16 |
2 files changed, 19 insertions, 2 deletions
diff --git a/src/soc/intel/skylake/include/soc/pcr.h b/src/soc/intel/skylake/include/soc/pcr.h index 9ac9eddd48..a6987cb33a 100644 --- a/src/soc/intel/skylake/include/soc/pcr.h +++ b/src/soc/intel/skylake/include/soc/pcr.h @@ -16,9 +16,12 @@ #ifndef _SOC_PCR_H_ #define _SOC_PCR_H_ +/* + * Primary to sideband (P2SB) for private configuration registers (PCR). + */ + /* PCH (SunRisePoint LP) */ #define PCH_PCR_BASE_ADDRESS 0xFD000000 -#define R_PCH_PCR_LPC_GCFD 0x3418 /* DMI Control Register */ #define R_PCH_PCR_DMI_DMIC 0x2234 diff --git a/src/soc/intel/skylake/pcr.c b/src/soc/intel/skylake/pcr.c index 33d6cd12f5..79c32f90a7 100644 --- a/src/soc/intel/skylake/pcr.c +++ b/src/soc/intel/skylake/pcr.c @@ -70,6 +70,19 @@ u8 pcr_read8(PCH_SBI_PID pid, u16 offset, u8 *outdata) } /* + * After every write one needs to perform a 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. + */ +static inline void complete_write(void) +{ + /* Read the general control and function disable register. */ + const size_t R_PCH_PCR_LPC_GCFD = 0x3418; + read32(PCH_PCR_ADDRESS(PID_LPC, R_PCH_PCR_LPC_GCFD)); +} + +/* * Write PCR register. (This is internal function) * It returns PCR register and size in 1/2/4 bytes. * The offset should not exceed 0xFFFF and must be aligned with size @@ -101,7 +114,8 @@ static u8 pch_pcr_write(PCH_SBI_PID pid, u16 offset, u32 size, u32 data) default: break; } - read32(PCH_PCR_ADDRESS(PID_LPC, R_PCH_PCR_LPC_GCFD)); + /* Ensure the writes complete. */ + complete_write(); return 0; } |