summaryrefslogtreecommitdiff
path: root/src/southbridge
diff options
context:
space:
mode:
authorMarshall Dawson <marshalldawson3rd@gmail.com>2017-02-10 16:03:54 -0700
committerMarc Jones <marc@marcjonesconsulting.com>2017-03-07 23:01:36 +0100
commit91dea4a6482cf6ebe4d4bc434fbcd566cedb3941 (patch)
treed6e99903be2abc4b64b9fe7a45969fc51d7ebb63 /src/southbridge
parent7b0b9f0d418712613ce1eba4ad392c2def958285 (diff)
downloadcoreboot-91dea4a6482cf6ebe4d4bc434fbcd566cedb3941.tar.xz
amd/pi/hudson: Add early SPI setup
Add some generic functions that can configure the SPI interface to have faster performance. Given that the hudson files are used across many generations of FCHs, make sure to refer to the appropriate BKDG or RRG before using the functions. Notable differences: * Hudson 1 defines read mode in CNTRL0 differently than later gens * Hudson 1 supports setting NormSpeed in Cntr1 but Hudson3 allows setting FastSpeed as well * Kabini, Mullins, Carrizo and Stoney Ridge contain a "new" SPI100 controller Original-Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com> Original-Reviewed-by: Marc Jones <marcj303@gmail.com> (cherry picked from commit 1922d6f424dcf1f42e2f21fb7c6d53d7bcc247d0) Change-Id: Id12440e67bc575dbe4b980ef1da931d7bfae188d Signed-off-by: Marc Jones <marcj303@gmail.com> Reviewed-on: https://review.coreboot.org/18442 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Diffstat (limited to 'src/southbridge')
-rw-r--r--src/southbridge/amd/pi/hudson/early_setup.c53
-rw-r--r--src/southbridge/amd/pi/hudson/hudson.h4
2 files changed, 57 insertions, 0 deletions
diff --git a/src/southbridge/amd/pi/hudson/early_setup.c b/src/southbridge/amd/pi/hudson/early_setup.c
index 553add9f5d..7277362191 100644
--- a/src/southbridge/amd/pi/hudson/early_setup.c
+++ b/src/southbridge/amd/pi/hudson/early_setup.c
@@ -190,4 +190,57 @@ void hudson_clk_output_48Mhz(void)
*memptr = data;
}
+static uintptr_t hudson_spibase(void)
+{
+ /* Make sure the base address is predictable */
+ device_t dev = PCI_DEV(0, 0x14, 3);
+
+ u32 base = pci_read_config32(dev, SPIROM_BASE_ADDRESS_REGISTER)
+ & 0xfffffff0;
+ if (!base){
+ base = SPI_BASE_ADDRESS;
+ pci_write_config32(dev, SPIROM_BASE_ADDRESS_REGISTER, base
+ | SPI_ROM_ENABLE);
+ /* PCI_COMMAND_MEMORY is read-only and enabled. */
+ }
+ return (uintptr_t)base;
+}
+
+void hudson_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm)
+{
+ uintptr_t base = hudson_spibase();
+ write16((void *)base + SPI100_SPEED_CONFIG,
+ (norm << SPI_NORM_SPEED_NEW_SH) |
+ (fast << SPI_FAST_SPEED_NEW_SH) |
+ (alt << SPI_ALT_SPEED_NEW_SH) |
+ (tpm << SPI_TPM_SPEED_NEW_SH));
+ write16((void *)base + SPI100_ENABLE, SPI_USE_SPI100);
+}
+
+void hudson_disable_4dw_burst(void)
+{
+ uintptr_t base = hudson_spibase();
+ write16((void *)base + SPI100_HOST_PREF_CONFIG,
+ read16((void *)base + SPI100_HOST_PREF_CONFIG)
+ & ~SPI_RD4DW_EN_HOST);
+}
+
+/* Hudson 1-3 only. For Hudson 1, call with fast=1 */
+void hudson_set_readspeed(u16 norm, u16 fast)
+{
+ uintptr_t base = hudson_spibase();
+ write16((void *)base + SPI_CNTRL1, (read16((void *)base + SPI_CNTRL1)
+ & ~SPI_CNTRL1_SPEED_MASK)
+ | (norm << SPI_NORM_SPEED_SH)
+ | (fast << SPI_FAST_SPEED_SH));
+}
+
+void hudson_read_mode(u32 mode)
+{
+ uintptr_t base = hudson_spibase();
+ write32((void *)base + SPI_CNTRL0,
+ (read32((void *)base + SPI_CNTRL0)
+ & ~SPI_READ_MODE_MASK) | mode);
+}
+
#endif
diff --git a/src/southbridge/amd/pi/hudson/hudson.h b/src/southbridge/amd/pi/hudson/hudson.h
index cb0f27347e..6e3157dd14 100644
--- a/src/southbridge/amd/pi/hudson/hudson.h
+++ b/src/southbridge/amd/pi/hudson/hudson.h
@@ -148,6 +148,10 @@ void hudson_lpc_port80(void);
void hudson_lpc_decode(void);
void hudson_pci_port80(void);
void hudson_clk_output_48Mhz(void);
+void hudson_read_mode(u32 mode);
+void hudson_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm);
+void hudson_disable_4dw_burst(void);
+void hudson_set_readspeed(u16 norm, u16 fast);
int s3_save_nvram_early(u32 dword, int size, int nvram_pos);
int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos);