summaryrefslogtreecommitdiff
path: root/src/soc/amd
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/amd')
-rw-r--r--src/soc/amd/stoneyridge/include/soc/southbridge.h3
-rw-r--r--src/soc/amd/stoneyridge/lpc.c2
-rw-r--r--src/soc/amd/stoneyridge/southbridge.c56
3 files changed, 41 insertions, 20 deletions
diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h
index 6734efb04d..0ac43857e5 100644
--- a/src/soc/amd/stoneyridge/include/soc/southbridge.h
+++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h
@@ -357,12 +357,11 @@
#define LPC_WIDEIO2_GENERIC_PORT 0x90
#define SPIROM_BASE_ADDRESS_REGISTER 0xa0
-#define SPI_BASE_RESERVED (BIT(4) | BIT(5))
+#define SPI_BASE_ALIGNMENT BIT(6)
#define ROUTE_TPM_2_SPI BIT(3)
#define SPI_ABORT_ENABLE BIT(2)
#define SPI_ROM_ENABLE BIT(1)
#define SPI_ROM_ALT_ENABLE BIT(0)
-#define SPI_PRESERVE_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3))
/* LPC register 0xb8 is DWORD, here there are definitions for byte
access. For example, bits 31-24 are accessed through byte access
diff --git a/src/soc/amd/stoneyridge/lpc.c b/src/soc/amd/stoneyridge/lpc.c
index 3ace1fdce6..1741e92e0c 100644
--- a/src/soc/amd/stoneyridge/lpc.c
+++ b/src/soc/amd/stoneyridge/lpc.c
@@ -146,7 +146,7 @@ static void lpc_set_resources(struct device *dev)
/* Special case. The SpiRomEnable and other enables should STAY set. */
res = find_resource(dev, 2);
spi_enable_bits = pci_read_config32(dev, SPIROM_BASE_ADDRESS_REGISTER);
- spi_enable_bits &= SPI_PRESERVE_BITS;
+ spi_enable_bits &= SPI_BASE_ALIGNMENT - 1;
pci_write_config32(dev, SPIROM_BASE_ADDRESS_REGISTER,
res->base | spi_enable_bits);
diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c
index 84db3dd76c..b8d0595965 100644
--- a/src/soc/amd/stoneyridge/southbridge.c
+++ b/src/soc/amd/stoneyridge/southbridge.c
@@ -397,27 +397,49 @@ void sb_clk_output_48Mhz(u32 osc)
misc_write32(MISC_CLK_CNTL1, ctrl);
}
-static uintptr_t sb_spibase(void)
+static uintptr_t sb_get_spibase(void)
{
- u32 base, enables;
+ u32 base;
- /* Make sure the base address is predictable */
base = pci_read_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER);
- enables = base & SPI_PRESERVE_BITS;
- base &= ~(SPI_PRESERVE_BITS | SPI_BASE_RESERVED);
-
- if (!base) {
- base = SPI_BASE_ADDRESS;
- pci_write_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER,
- base | enables | SPI_ROM_ENABLE);
- /* PCI_COMMAND_MEMORY is read-only and enabled. */
- }
+ base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT);
return (uintptr_t)base;
}
+static void sb_set_spibase(u32 base, u32 enable)
+{
+ u32 reg32;
+
+ /* only two types of CS# enables are allowed */
+ enable &= SPI_ROM_ENABLE | SPI_ROM_ALT_ENABLE;
+
+ reg32 = pci_read_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER);
+
+ reg32 &= SPI_BASE_ALIGNMENT - 1; /* preserve only reserved, enables */
+ reg32 &= ~(SPI_ROM_ENABLE | SPI_ROM_ALT_ENABLE);
+ reg32 |= enable;
+ reg32 |= ALIGN_DOWN(base, SPI_BASE_ALIGNMENT);
+
+ pci_write_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER, reg32);
+}
+
+static uintptr_t sb_init_spi_base(void)
+{
+ uintptr_t base;
+
+ /* Make sure the base address is predictable */
+ base = sb_get_spibase();
+
+ if (base)
+ return base;
+
+ sb_set_spibase(SPI_BASE_ADDRESS, SPI_ROM_ENABLE);
+ return SPI_BASE_ADDRESS;
+}
+
void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm)
{
- uintptr_t base = sb_spibase();
+ uintptr_t base = sb_init_spi_base();
write16((void *)(base + SPI100_SPEED_CONFIG),
(norm << SPI_NORM_SPEED_NEW_SH) |
(fast << SPI_FAST_SPEED_NEW_SH) |
@@ -428,7 +450,7 @@ void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm)
void sb_disable_4dw_burst(void)
{
- uintptr_t base = sb_spibase();
+ uintptr_t base = sb_init_spi_base();
write16((void *)(base + SPI100_HOST_PREF_CONFIG),
read16((void *)(base + SPI100_HOST_PREF_CONFIG))
& ~SPI_RD4DW_EN_HOST);
@@ -436,7 +458,7 @@ void sb_disable_4dw_burst(void)
void sb_read_mode(u32 mode)
{
- uintptr_t base = sb_spibase();
+ uintptr_t base = sb_init_spi_base();
write32((void *)(base + SPI_CNTRL0),
(read32((void *)(base + SPI_CNTRL0))
& ~SPI_READ_MODE_MASK) | mode);
@@ -466,7 +488,7 @@ void sb_tpm_decode(void)
* Enable FCH to decode TPM associated Memory and IO regions to SPI
*
* This should be used if TPM is connected to SPI bus.
- * Assumes SPI address space is already configured via a call to sb_spibase().
+ * Assumes SPI address space is already configured.
*/
void sb_tpm_decode_spi(void)
{
@@ -631,7 +653,7 @@ void bootblock_fch_early_init(void)
sb_lpc_port80();
sb_lpc_decode();
sb_lpc_early_setup();
- sb_spibase();
+ sb_init_spi_base();
sb_disable_4dw_burst(); /* Must be disabled on CZ(ST) */
enable_acpimmio_decode();
fch_smbus_init();