<p>Richard Spiegel has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/21767">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/amd/stoneyridge: Replace magic registers<br><br>Replace southbridge registers and register values from magic numbers to<br>literals, provided these registers are currently defined in publicly or<br>NDA datasheet.<br>Registers available only internally to AMD are left unchanged.<br><br>Code Files: smbus_spd.c, lpc.c, early_setup.c<br>Include Files: smbus.h, southbridge.h<br><br>Change-Id: I9187ba1c41ebb1201ddc177e8184672c60cd5f5d<br>Signed-off-by: Richard Spiegel <richard.spiegel@amd.corp-partner.google.com><br>---<br>M src/soc/amd/stoneyridge/early_setup.c<br>M src/soc/amd/stoneyridge/include/soc/smbus.h<br>M src/soc/amd/stoneyridge/include/soc/southbridge.h<br>M src/soc/amd/stoneyridge/lpc.c<br>M src/soc/amd/stoneyridge/smbus_spd.c<br>5 files changed, 432 insertions(+), 206 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/67/21767/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/soc/amd/stoneyridge/early_setup.c b/src/soc/amd/stoneyridge/early_setup.c<br>index 5166a7f..e4c16ba 100644<br>--- a/src/soc/amd/stoneyridge/early_setup.c<br>+++ b/src/soc/amd/stoneyridge/early_setup.c<br>@@ -33,11 +33,11 @@<br> <br> byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56<br> + CONFIG_UART_FOR_CONSOLE * 2);<br>- byte |= 1 << 3;<br>+ byte |= AOAC_PWR_ON_DEV;<br> write8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56<br> + CONFIG_UART_FOR_CONSOLE * 2, byte);<br> byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG62);<br>- byte |= 1 << 3;<br>+ byte |= AOAC_PWR_ON_DEV;<br> write8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG62, byte);<br> write8((void *)FCH_IOMUXx89_UART0_RTS_L_EGPIO137, 0);<br> write8((void *)FCH_IOMUXx8A_UART0_TXD_EGPIO138, 0);<br>@@ -57,9 +57,9 @@<br> <br> dev = PCI_DEV(0, PCU_DEV, LPC_FUNC);<br> <br>- byte = pci_read_config8(dev, 0x4a);<br>- byte &= ~(1 << 5); /* disable lpc port 80 */<br>- pci_write_config8(dev, 0x4a, byte);<br>+ byte = pci_read_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH);<br>+ byte &= ~DECODE_IO_PORT_ENABLE4_H; /* disable lpc port 80 */<br>+ pci_write_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH, byte);<br> }<br> <br> void sb_lpc_port80(void)<br>@@ -68,17 +68,17 @@<br> pci_devfn_t dev;<br> <br> /* Enable LPC controller */<br>- outb(0xec, PM_INDEX);<br>+ outb(PM_LPC_GATING, PM_INDEX);<br> byte = inb(PM_DATA);<br>- byte |= 1;<br>- outb(0xec, PM_INDEX);<br>+ byte |= PM_LPC_ENABLE;<br>+ outb(PM_LPC_GATING, PM_INDEX);<br> outb(byte, PM_DATA);<br> <br> /* Enable port 80 LPC decode in pci function 3 configuration space. */<br> dev = PCI_DEV(0, PCU_DEV, LPC_FUNC);<br>- byte = pci_read_config8(dev, 0x4a);<br>- byte |= 1 << 5; /* enable port 80 */<br>- pci_write_config8(dev, 0x4a, byte);<br>+ byte = pci_read_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH);<br>+ byte |= DECODE_IO_PORT_ENABLE4_H; /* enable port 80 */<br>+ pci_write_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH, byte);<br> }<br> <br> void sb_lpc_decode(void)<br>@@ -233,7 +233,7 @@<br> ctrl = read32((void *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40));<br> <br> /* clear the OSCOUT1_ClkOutputEnb to enable the 48 Mhz clock */<br>- ctrl &= ~(1<<2);<br>+ ctrl &= ~FCH_MISC_REG40_OSCOUT1_EN;<br> write32((void *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40), ctrl);<br> }<br> <br>@@ -317,16 +317,18 @@<br> <br> dev = PCI_DEV(0, PCU_DEV, LPC_FUNC);<br> <br>- /* Decode variable LPC ROM address ranges 1 and 2. */<br>- reg8 = pci_io_read_config8(dev, 0x48);<br>+ /* Decode variable LPC ROM address ranges 1 and 2.<br>+ * Bits 3-4 are not defined in any publicly available datasheet<br>+ */<br>+ reg8 = pci_io_read_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE);<br> reg8 |= (1 << 3) | (1 << 4);<br>- pci_io_write_config8(dev, 0x48, reg8);<br>+ pci_io_write_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE, reg8);<br> <br> /* LPC ROM address range 1: */<br> /* Enable LPC ROM range mirroring start at 0x000e(0000). */<br>- pci_io_write_config16(dev, 0x68, 0x000e);<br>+ pci_io_write_config16(dev, ROM_ADDRESS_RANGE1_START, 0x000e);<br> /* Enable LPC ROM range mirroring end at 0x000f(ffff). */<br>- pci_io_write_config16(dev, 0x6a, 0x000f);<br>+ pci_io_write_config16(dev, ROM_ADDRESS_RANGE1_END, 0x000f);<br> <br> /* LPC ROM address range 2: */<br> /*<br>@@ -336,10 +338,10 @@<br> * 0xffe0(0000): 2MB<br> * 0xffc0(0000): 4MB<br> */<br>- pci_io_write_config16(dev, 0x6c, 0x10000<br>+ pci_io_write_config16(dev, ROM_ADDRESS_RANGE2_START, 0x10000<br> - (CONFIG_COREBOOT_ROMSIZE_KB >> 6));<br> /* Enable LPC ROM range end at 0xffff(ffff). */<br>- pci_io_write_config16(dev, 0x6e, 0xffff);<br>+ pci_io_write_config16(dev, ROM_ADDRESS_RANGE2_END, 0xffff);<br> }<br> <br> void bootblock_fch_early_init(void)<br>diff --git a/src/soc/amd/stoneyridge/include/soc/smbus.h b/src/soc/amd/stoneyridge/include/soc/smbus.h<br>index 90a59e4..a9b80eb 100644<br>--- a/src/soc/amd/stoneyridge/include/soc/smbus.h<br>+++ b/src/soc/amd/stoneyridge/include/soc/smbus.h<br>@@ -19,17 +19,46 @@<br> #include <stdint.h><br> <br> #define SMBHSTSTAT 0x0<br>-#define SMBSLVSTAT 0x1<br>+#define SMBHST_STAT_FAILED 0x10<br>+#define SMBHST_STAT_COLLISION 0x08<br>+#define SMBHST_STAT_ERROR 0x04<br>+#define SMBHST_STAT_INTERRUPT 0x02<br>+#define SMBHST_STAT_BUSY 0x01<br>+#define SMBHST_STAT_CLEAR 0xff<br>+#define SMBHST_STAT_NOERROR 0x02<br>+<br>+#define SMBSLVSTAT 0x1<br>+#define SMBSLV_STAT_ALERT 0x20<br>+#define SMBSLV_STAT_SHADOW2 0x10<br>+#define SMBSLV_STAT_SHADOW1 0x08<br>+#define SMBSLV_STAT_SLV_STS 0x04<br>+#define SMBSLV_STAT_SLV_INIT 0x02<br>+#define SMBSLV_STAT_SLV_BUSY 0x01<br>+#define SMBSLV_STAT_CLEAR 0x1f<br>+<br> #define SMBHSTCTRL 0x2<br>+#define SMBHST_CTRL_RST 0x80<br>+#define SMBHST_CTRL_STRT 0x40<br>+#define SMBHST_CTRL_QCK_RW 0x00<br>+#define SMBHST_CTRL_BTE_RW 0x04<br>+#define SMBHST_CTRL_BDT_RW 0x08<br>+#define SMBHST_CTRL_WDT_RW 0x0c<br>+#define SMBHST_CTRL_BLK_RW 0x14<br>+#define SMBHST_CTRL_KILL 0x02<br>+#define SMBHST_CTRL_IEN 0x01<br>+<br> #define SMBHSTCMD 0x3<br> #define SMBHSTADDR 0x4<br> #define SMBHSTDAT0 0x5<br> #define SMBHSTDAT1 0x6<br>-#define SMBHSTBLKDAT 0x7<br>+#define SMBHSTBLKDAT 0x7<br> #define SMBSLVCTRL 0x8<br> #define SMBSLVCMD_SHADOW 0x9<br> #define SMBSLVEVT 0xa<br> #define SMBSLVDAT 0xc<br>+#define SMBTIMING 0xe<br>+<br>+#define SMB_BASE_ADDR 0xb00<br> <br> #define AX_INDXC 0<br> #define AX_INDXP 2<br>diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h<br>index 20edf5f..31f4b8e 100644<br>--- a/src/soc/amd/stoneyridge/include/soc/southbridge.h<br>+++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h<br>@@ -23,6 +23,109 @@<br> #include <device/device.h><br> #include "chip.h"<br> <br>+/* Some older include files such as fch.h use predefined bits values<br>+ * instead of using BIT(x) macro. As they are used in early_setup.c,<br>+ * they need to be defined, and southbridge.h needs to be included<br>+ * before the ofending file.<br>+ */<br>+<br>+#ifndef BIT0<br>+#define BIT0 BIT(0)<br>+#endif<br>+#ifndef BIT1<br>+#define BIT1 BIT(1)<br>+#endif<br>+#ifndef BIT2<br>+#define BIT2 BIT(2)<br>+#endif<br>+#ifndef BIT3<br>+#define BIT3 BIT(3)<br>+#endif<br>+#ifndef BIT4<br>+#define BIT4 BIT(4)<br>+#endif<br>+#ifndef BIT5<br>+#define BIT5 BIT(5)<br>+#endif<br>+#ifndef BIT6<br>+#define BIT6 BIT(6)<br>+#endif<br>+#ifndef BIT7<br>+#define BIT7 BIT(7)<br>+#endif<br>+#ifndef BIT8<br>+#define BIT8 BIT(8)<br>+#endif<br>+#ifndef BIT9<br>+#define BIT9 BIT(9)<br>+#endif<br>+#ifndef BIT10<br>+#define BIT10 BIT(10)<br>+#endif<br>+#ifndef BIT11<br>+#define BIT11 BIT(11)<br>+#endif<br>+#ifndef BIT12<br>+#define BIT12 BIT(12)<br>+#endif<br>+#ifndef BIT13<br>+#define BIT13 BIT(13)<br>+#endif<br>+#ifndef BIT14<br>+#define BIT14 BIT(14)<br>+#endif<br>+#ifndef BIT15<br>+#define BIT15 BIT(15)<br>+#endif<br>+#ifndef BIT16<br>+#define BIT16 BIT(16)<br>+#endif<br>+#ifndef BIT17<br>+#define BIT17 BIT(17)<br>+#endif<br>+#ifndef BIT18<br>+#define BIT18 BIT(18)<br>+#endif<br>+#ifndef BIT19<br>+#define BIT19 BIT(19)<br>+#endif<br>+#ifndef BIT20<br>+#define BIT20 BIT(20)<br>+#endif<br>+#ifndef BIT21<br>+#define BIT21 BIT(21)<br>+#endif<br>+#ifndef BIT22<br>+#define BIT22 BIT(22)<br>+#endif<br>+#ifndef BIT23<br>+#define BIT23 BIT(23)<br>+#endif<br>+#ifndef BIT24<br>+#define BIT24 BIT(24)<br>+#endif<br>+#ifndef BIT25<br>+#define BIT25 BIT(25)<br>+#endif<br>+#ifndef BIT26<br>+#define BIT26 BIT(26)<br>+#endif<br>+#ifndef BIT27<br>+#define BIT27 BIT(27)<br>+#endif<br>+#ifndef BIT28<br>+#define BIT28 BIT(28)<br>+#endif<br>+#ifndef BIT29<br>+#define BIT29 BIT(29)<br>+#endif<br>+#ifndef BIT30<br>+#define BIT30 BIT(30)<br>+#endif<br>+#ifndef BIT31<br>+#define BIT31 BIT(31)<br>+#endif<br>+<br> #define IO_APIC2_ADDR 0xfec20000<br> <br> /* Offsets from ACPI_MMIO_BASE<br>@@ -37,25 +140,40 @@<br> /* Power management index/data registers */<br> #define BIOSRAM_INDEX 0xcd4<br> #define BIOSRAM_DATA 0xcd5<br>-#define PM_INDEX 0xcd6<br>-#define PM_DATA 0xcd7<br>-#define PM2_INDEX 0xcd0<br>-#define PM2_DATA 0xcd1<br>+#define PM_INDEX 0xcd6<br>+#define PM_DATA 0xcd7<br>+#define PM2_INDEX 0xcd0<br>+#define PM2_DATA 0xcd1<br> <br> #define PM_ACPI_MMIO_EN 0x24<br> #define PM_SERIRQ_CONF 0x54<br>-#define PM_EVT_BLK 0x60<br>-#define PM1_CNT_BLK 0x62<br>-#define PM_TMR_BLK 0x64<br>-#define PM_CPU_CTRL 0x66<br>-#define PM_GPE0_BLK 0x68<br>+#define PM_SERIRQ_NUM_BITS_17 0x0000<br>+#define PM_SERIRQ_NUM_BITS_18 0x0004<br>+#define PM_SERIRQ_NUM_BITS_19 0x0008<br>+#define PM_SERIRQ_NUM_BITS_20 0x000c<br>+#define PM_SERIRQ_NUM_BITS_21 0x0010<br>+#define PM_SERIRQ_NUM_BITS_22 0x0014<br>+#define PM_SERIRQ_NUM_BITS_23 0x0018<br>+#define PM_SERIRQ_NUM_BITS_24 0x001c<br>+#define PM_SERIRQ_MODE BIT(6)<br>+#define PM_SERIRQ_ENABLE BIT(7)<br>+<br>+#define PM_EVT_BLK 0x60<br>+#define PM1_CNT_BLK 0x62<br>+#define PM_TMR_BLK 0x64<br>+#define PM_CPU_CTRL 0x66<br>+#define PM_GPE0_BLK 0x68<br> #define PM_ACPI_SMI_CMD 0x6a<br> #define PM_ACPI_CONF 0x74<br> #define PM_PMIO_DEBUG 0xd2<br> #define PM_MANUAL_RESET 0xd3<br>-#define PM_HUD_SD_FLASH_CTRL 0xe7<br>-#define PM_YANG_SD_FLASH_CTRL 0xe8<br>-#define PM_PCIB_CFG 0xea<br>+#define PM_HUD_SD_FLASH_CTRL 0xe7<br>+#define PM_YANG_SD_FLASH_CTRL 0xe8<br>+#define PM_PCIB_CFG 0xea<br>+#define PM_LPC_GATING 0xec<br>+#define PM_LPC_AB_NO_BYPASS_EN BIT(2)<br>+#define PM_LPC_A20_EN BIT(1)<br>+#define PM_LPC_ENABLE BIT(0)<br> <br> #define SYS_RESET 0xcf9<br> <br>@@ -78,8 +196,14 @@<br> <br> #define SPIROM_BASE_ADDRESS_REGISTER 0xa0<br> #define ROUTE_TPM_2_SPI BIT(3)<br>-#define SPI_ROM_ENABLE 0x02<br>+#define SPI_ABORT_ENABLE BIT(2)<br>+#define SPI_ROM_ENABLE BIT(1)<br>+#define SPI_ROM_ALT_ENABLE BIT(0)<br>+#define SPI_PRESERVE_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3))<br> #define SPI_BASE_ADDRESS 0xfec10000<br>+<br>+#define LPC_PCI_CONTROL 0x40<br>+#define LEGACY_DMA_EN BIT(2)<br> <br> #define LPC_IO_PORT_DECODE_ENABLE 0x44<br> #define DECODE_ENABLE_PARALLEL_PORT0 BIT(0)<br>@@ -118,16 +242,55 @@<br> #define LPC_IO_OR_MEM_DECODE_ENABLE 0x48<br> #define LPC_WIDEIO2_ENABLE BIT(25)<br> #define LPC_WIDEIO1_ENABLE BIT(24)<br>+#define DECODE_IO_PORT_ENABLE6 BIT(23)<br>+#define DECODE_IO_PORT_ENABLE5 BIT(22)<br>+#define DECODE_IO_PORT_ENABLE4 BIT(21)<br>+#define DECODE_IO_PORT_ENABLE3 BIT(19)<br>+#define DECODE_IO_PORT_ENABLE2 BIT(18)<br>+#define DECODE_IO_PORT_ENABLE1 BIT(17)<br>+#define DECODE_IO_PORT_ENABLE0 BIT(16)<br>+#define LPC_SYNC_TIMEOUT_COUNT_ENABLE BIT(7)<br> #define LPC_WIDEIO0_ENABLE BIT(2)<br>+/* Assuming word access to higher word (register 0x4a) */<br>+#define LPC_IO_OR_MEM_DEC_EN_HIGH 0x4a<br>+#define LPC_WIDEIO2_ENABLE_H BIT(9)<br>+#define LPC_WIDEIO1_ENABLE_H BIT(8)<br>+#define DECODE_IO_PORT_ENABLE6_H BIT(7)<br>+#define DECODE_IO_PORT_ENABLE5_H BIT(6)<br>+#define DECODE_IO_PORT_ENABLE4_H BIT(5)<br>+#define DECODE_IO_PORT_ENABLE3_H BIT(3)<br>+#define DECODE_IO_PORT_ENABLE2_H BIT(2)<br>+#define DECODE_IO_PORT_ENABLE1_H BIT(1)<br>+#define DECODE_IO_PORT_ENABLE0_H BIT(0)<br> <br>+/* Register 0x64 is 32-bit, composed by two 16-bit sub-registers.<br>+ * For ease of access, each sub-register is declared separetely.<br>+ */<br> #define LPC_WIDEIO_GENERIC_PORT 0x64<br>+#define LPC_WIDEIO1_GENERIC_PORT 0x66<br>+#define ROM_ADDRESS_RANGE1_START 0x68<br>+#define ROM_ADDRESS_RANGE1_END 0x6a<br>+#define ROM_ADDRESS_RANGE2_START 0x6c<br>+#define ROM_ADDRESS_RANGE2_END 0x6e<br> <br> #define LPC_ALT_WIDEIO_RANGE_ENABLE 0x74<br> #define LPC_ALT_WIDEIO2_ENABLE BIT(3)<br> #define LPC_ALT_WIDEIO1_ENABLE BIT(2)<br> #define LPC_ALT_WIDEIO0_ENABLE BIT(0)<br> <br>+#define LPC_MISC_CONTROL_BITS 0x78<br>+#define LPC_NOHOG BIT(0)<br>+<br> #define LPC_WIDEIO2_GENERIC_PORT 0x90<br>+<br>+/* LPC register 0xb8 is DWORD, here there are definition for byte<br>+ * access. For example, bits 31-24 are accessed through byte access<br>+ * at register 0xbb ().<br>+ */<br>+#define LPC_ROM_DMA_EC_HOST_CONTROL 0xb8<br>+<br>+#define LPC_HOST_CONTROL 0xbb<br>+#define SPI_FROM_HOST_PREFETCH_EN BIT(0)<br> <br> #define SPI_CNTRL0 0x00<br> #define SPI_READ_MODE_MASK (BIT(30) | BIT(29) | BIT(18))<br>@@ -165,6 +328,10 @@<br> #define SPI100_HOST_PREF_CONFIG 0x2c<br> #define SPI_RD4DW_EN_HOST BIT(15)<br> <br>+#define FCH_MISC_REG40_OSCOUT1_EN BIT(2)<br>+<br>+#define FLASH_BASE_ADDR ((0xffffffff - CONFIG_ROM_SIZE) + 1)<br>+<br> static inline int sb_sata_enable(void)<br> {<br> /* True if IDE or AHCI. */<br>diff --git a/src/soc/amd/stoneyridge/lpc.c b/src/soc/amd/stoneyridge/lpc.c<br>index 7886433..1580d0e 100644<br>--- a/src/soc/amd/stoneyridge/lpc.c<br>+++ b/src/soc/amd/stoneyridge/lpc.c<br>@@ -40,7 +40,9 @@<br> u32 dword;<br> device_t sm_dev;<br> <br>- /* Enable the LPC Controller */<br>+ /* Enable the LPC Controller<br>+ * SMBUS register 0x64 is not defined in public datasheet.<br>+ */<br> sm_dev = dev_find_slot(0, PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC));<br> dword = pci_read_config32(sm_dev, 0x64);<br> dword |= 1 << 20;<br>@@ -50,33 +52,33 @@<br> isa_dma_init();<br> <br> /* Enable DMA transaction on the LPC bus */<br>- byte = pci_read_config8(dev, 0x40);<br>- byte |= (1 << 2);<br>- pci_write_config8(dev, 0x40, byte);<br>+ byte = pci_read_config8(dev, LPC_PCI_CONTROL);<br>+ byte |= LEGACY_DMA_EN;<br>+ pci_write_config8(dev, LPC_PCI_CONTROL, byte);<br> <br> /* Disable the timeout mechanism on LPC */<br>- byte = pci_read_config8(dev, 0x48);<br>- byte &= ~(1 << 7);<br>- pci_write_config8(dev, 0x48, byte);<br>+ byte = pci_read_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE);<br>+ byte &= ~LPC_SYNC_TIMEOUT_COUNT_ENABLE;<br>+ pci_write_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE, byte);<br> <br> /* Disable LPC MSI Capability */<br>- byte = pci_read_config8(dev, 0x78);<br>+ byte = pci_read_config8(dev, LPC_MISC_CONTROL_BITS);<br>+ /* BIT 1 is not defined in public datasheet. */<br> byte &= ~(1 << 1);<br>+<br> /* Keep the old way. i.e., when bus master/DMA cycle is going<br> * on on LPC, it holds PCI grant, so no LPC slave cycle can<br> * interrupt and visit LPC.<br> */<br>- byte &= ~(1 << 0);<br>- pci_write_config8(dev, 0x78, byte);<br>+ byte &= ~LPC_NOHOG;<br>+ pci_write_config8(dev, LPC_MISC_CONTROL_BITS, byte);<br> <br>- /* bit0: Enable prefetch a cacheline (64 bytes) when Host reads<br>- * code from SPI ROM<br>- * bit3: Fix SPI_CS# timing issue when running at 66M. TODO:A12.<br>- * todo: verify both these against BKDG<br>+ /* bit3: Fix SPI_CS# timing issue when running at 66M. TODO:A12.<br>+ * todo: verify against BKDG<br> */<br>- byte = pci_read_config8(dev, 0xbb);<br>- byte |= 1 << 0 | 1 << 3;<br>- pci_write_config8(dev, 0xbb, byte);<br>+ byte = pci_read_config8(dev, LPC_HOST_CONTROL);<br>+ byte |= SPI_FROM_HOST_PREFETCH_EN | 1 << 3;<br>+ pci_write_config8(dev, LPC_HOST_CONTROL, byte);<br> <br> cmos_check_update_date();<br> <br>@@ -94,9 +96,9 @@<br> setup_i8254();<br> <br> /* Set up SERIRQ, enable continuous mode */<br>- byte = (BIT(4) | BIT(7));<br>+ byte = (PM_SERIRQ_NUM_BITS_21 | PM_SERIRQ_ENABLE);<br> if (!IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE))<br>- byte |= BIT(6);<br>+ byte |= PM_SERIRQ_MODE;<br> <br> pm_write8(PM_SERIRQ_CONF, byte);<br> }<br>@@ -117,8 +119,8 @@<br> IORESOURCE_ASSIGNED | IORESOURCE_FIXED;<br> <br> res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));<br>- res->base = 0xff800000;<br>- res->size = 0x00800000; /* 8 MB for flash */<br>+ res->base = FLASH_BASE_ADDR;<br>+ res->size = CONFIG_ROM_SIZE;<br> res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |<br> IORESOURCE_ASSIGNED | IORESOURCE_FIXED;<br> <br>@@ -145,11 +147,141 @@<br> /* Special case. The SpiRomEnable and other enables should STAY set. */<br> res = find_resource(dev, 2);<br> spi_enable_bits = pci_read_config32(dev, SPIROM_BASE_ADDRESS_REGISTER);<br>- spi_enable_bits &= 0xf;<br>+ spi_enable_bits &= SPI_PRESERVE_BITS;<br> pci_write_config32(dev, SPIROM_BASE_ADDRESS_REGISTER,<br> res->base | spi_enable_bits);<br> <br> pci_dev_set_resources(dev);<br>+}<br>+<br>+static void set_lpc_resource(device_t child,<br>+ int *variable_num,<br>+ u16 *reg_var,<br>+ u32 *reg,<br>+ u32 *reg_x,<br>+ u16 reg_size,<br>+ u8 *wiosize)<br>+{<br>+ struct resource *res;<br>+ u32 base, end; /* don't need long long */<br>+ u32 rsize = 0, set = 0, set_x = 0;<br>+ u16 var_num;<br>+<br>+ var_num = *variable_num;<br>+ for (res = child->resource_list ; res ; res = res->next) {<br>+ if (!(res->flags & IORESOURCE_IO))<br>+ continue;<br>+ base = res->base;<br>+ end = resource_end(res);<br>+ printk(BIOS_DEBUG,<br>+ "Southbridge LPC decode:%s, base=0x%08x, end=0x%08x\n",<br>+ dev_path(child), base, end);<br>+ /* find a resource size */<br>+ switch (base) {<br>+ case 0x60: /* KB */<br>+ case 0x64: /* MS */<br>+ set |= DECODE_ENABLE_KBC_PORT;<br>+ rsize = 1;<br>+ break;<br>+ case 0x3f8: /* COM1 */<br>+ set |= DECODE_ENABLE_SERIAL_PORT0;<br>+ rsize = 8;<br>+ break;<br>+ case 0x2f8: /* COM2 */<br>+ set |= DECODE_ENABLE_SERIAL_PORT1;<br>+ rsize = 8;<br>+ break;<br>+ case 0x378: /* Parallel 1 */<br>+ set |= DECODE_ENABLE_PARALLEL_PORT0;<br>+ /* enable 0x778 for ECP mode */<br>+ set |= DECODE_ENABLE_PARALLEL_PORT1;<br>+ rsize = 8;<br>+ break;<br>+ case 0x3f0: /* FD0 */<br>+ set |= DECODE_ENABLE_FDC_PORT0;<br>+ rsize = 8;<br>+ break;<br>+ case 0x220: /* 0x220 - 0x227 */<br>+ set |= DECODE_ENABLE_SERIAL_PORT2;<br>+ rsize = 8;<br>+ break;<br>+ case 0x228: /* 0x228 - 0x22f */<br>+ set |= DECODE_ENABLE_SERIAL_PORT3;<br>+ rsize = 8;<br>+ break;<br>+ case 0x238: /* 0x238 - 0x23f */<br>+ set |= DECODE_ENABLE_SERIAL_PORT4;<br>+ rsize = 8;<br>+ break;<br>+ case 0x300: /* 0x300 - 0x301 */<br>+ set |= DECODE_ENABLE_MIDI_PORT0;<br>+ rsize = 2;<br>+ break;<br>+ case 0x400:<br>+ set_x |= DECODE_IO_PORT_ENABLE0;<br>+ rsize = 0x40;<br>+ break;<br>+ case 0x480:<br>+ set_x |= DECODE_IO_PORT_ENABLE1;<br>+ rsize = 0x40;<br>+ break;<br>+ case 0x500:<br>+ set_x |= DECODE_IO_PORT_ENABLE2;<br>+ rsize = 0x40;<br>+ break;<br>+ case 0x580:<br>+ set_x |= DECODE_IO_PORT_ENABLE3;<br>+ rsize = 0x40;<br>+ break;<br>+ case 0x4700:<br>+ set_x |= DECODE_IO_PORT_ENABLE5;<br>+ rsize = 0xc;<br>+ break;<br>+ case 0xfd60:<br>+ set_x |= DECODE_IO_PORT_ENABLE6;<br>+ rsize = 16;<br>+ break;<br>+ default:<br>+ rsize = 0;<br>+ /* try AGESA allocated region in region 0 */<br>+ if ((var_num > 0) && ((base >= reg_var[0]) &&<br>+ ((base + res->size) <= (reg_var[0] + reg_size))))<br>+ rsize = reg_size;<br>+ }<br>+ /* check if region found and matches the enable */<br>+ if (res->size <= rsize) {<br>+ *reg |= set;<br>+ *reg_x |= set_x;<br>+ /* check if we can fit resource in variable range */<br>+ } else if ((var_num < 3) &&<br>+ ((res->size <= 16) || (res->size == 512))) {<br>+ /* use variable ranges if pre-defined do not match */<br>+ switch (var_num) {<br>+ case 0:<br>+ *reg_x |= LPC_WIDEIO0_ENABLE;<br>+ if (res->size <= 16)<br>+ *wiosize |= LPC_ALT_WIDEIO0_ENABLE;<br>+ break;<br>+ case 1:<br>+ *reg_x |= LPC_WIDEIO1_ENABLE;<br>+ if (res->size <= 16)<br>+ *wiosize |= LPC_ALT_WIDEIO1_ENABLE;<br>+ break;<br>+ case 2:<br>+ *reg_x |= LPC_WIDEIO2_ENABLE;<br>+ if (res->size <= 16)<br>+ *wiosize |= LPC_ALT_WIDEIO2_ENABLE;<br>+ break;<br>+ }<br>+ reg_var[var_num++] = base & 0xffff;<br>+ } else {<br>+ printk(BIOS_ERR,<br>+ "cannot fit LPC decode region:");<br>+ printk(BIOS_ERR, "%s, base = 0x%08x, end = 0x%08x\n",<br>+ dev_path(child), base, end);<br>+ }<br>+ }<br>+ *variable_num = var_num;<br> }<br> <br> /**<br>@@ -165,7 +297,7 @@<br> int var_num = 0;<br> u16 reg_var[3];<br> u16 reg_size[1] = {512};<br>- u8 wiosize = pci_read_config8(dev, 0x74);<br>+ u8 wiosize = pci_read_config8(dev, LPC_ALT_WIDEIO_RANGE_ENABLE);<br> <br> /* Be a bit relaxed, tolerate that LPC region might be bigger than<br> * resource we try to fit, do it like this for all regions < 16 bytes.<br>@@ -177,26 +309,26 @@<br> * The code tries to check if resource can fit into this region.<br> */<br> <br>- reg = pci_read_config32(dev, 0x44);<br>- reg_x = pci_read_config32(dev, 0x48);<br>+ reg = pci_read_config32(dev, LPC_IO_PORT_DECODE_ENABLE);<br>+ reg_x = pci_read_config32(dev, LPC_IO_OR_MEM_DECODE_ENABLE);<br> <br> /* check if ranges are free and don't use them if already taken */<br>- if (reg_x & (1 << 2))<br>+ if (reg_x & LPC_WIDEIO0_ENABLE)<br> var_num = 1;<br> /* just in case check if someone did not manually set other ranges */<br>- if (reg_x & (1 << 24))<br>+ if (reg_x & LPC_WIDEIO1_ENABLE)<br> var_num = 2;<br> <br>- if (reg_x & (1 << 25))<br>+ if (reg_x & LPC_WIDEIO2_ENABLE)<br> var_num = 3;<br> <br> /* check AGESA region size */<br>- if (wiosize & (1 << 0))<br>+ if (wiosize & LPC_ALT_WIDEIO0_ENABLE)<br> reg_size[0] = 16;<br> <br>- reg_var[2] = pci_read_config16(dev, 0x90);<br>- reg_var[1] = pci_read_config16(dev, 0x66);<br>- reg_var[0] = pci_read_config16(dev, 0x64);<br>+ reg_var[2] = pci_read_config16(dev, LPC_WIDEIO2_GENERIC_PORT);<br>+ reg_var[1] = pci_read_config16(dev, LPC_WIDEIO1_GENERIC_PORT);<br>+ reg_var[0] = pci_read_config16(dev, LPC_WIDEIO_GENERIC_PORT);<br> <br> /* todo: clean up the code style here */<br> for (link = dev->link_list ; link ; link = link->next) {<br>@@ -205,137 +337,31 @@<br> child = child->sibling) {<br> if (child->enabled<br> && (child->path.type == DEVICE_PATH_PNP)) {<br>- struct resource *res;<br>- for (res = child->resource_list ; res ; res = res->next) {<br>- u32 base, end; /* don't need long long */<br>- u32 rsize, set = 0, set_x = 0;<br>- if (!(res->flags & IORESOURCE_IO))<br>- continue;<br>- base = res->base;<br>- end = resource_end(res);<br>- /* find a resource size */<br>- printk(BIOS_DEBUG, "Southbridge LPC decode:%s, base=0x%08x, end=0x%08x\n",<br>- dev_path(child), base, end);<br>- switch (base) {<br>- case 0x60: /* KB */<br>- case 0x64: /* MS */<br>- set |= (1 << 29);<br>- rsize = 1;<br>- break;<br>- case 0x3f8: /* COM1 */<br>- set |= (1 << 6);<br>- rsize = 8;<br>- break;<br>- case 0x2f8: /* COM2 */<br>- set |= (1 << 7);<br>- rsize = 8;<br>- break;<br>- case 0x378: /* Parallel 1 */<br>- set |= (1 << 0);<br>- set |= (1 << 1); /* + 0x778 for ECP */<br>- rsize = 8;<br>- break;<br>- case 0x3f0: /* FD0 */<br>- set |= (1 << 26);<br>- rsize = 8;<br>- break;<br>- case 0x220: /* 0x220 - 0x227 */<br>- set |= (1 << 8);<br>- rsize = 8;<br>- break;<br>- case 0x228: /* 0x228 - 0x22f */<br>- set |= (1 << 9);<br>- rsize = 8;<br>- break;<br>- case 0x238: /* 0x238 - 0x23f */<br>- set |= (1 << 10);<br>- rsize = 8;<br>- break;<br>- case 0x300: /* 0x300 - 0x301 */<br>- set |= (1 << 18);<br>- rsize = 2;<br>- break;<br>- case 0x400:<br>- set_x |= (1 << 16);<br>- rsize = 0x40;<br>- break;<br>- case 0x480:<br>- set_x |= (1 << 17);<br>- rsize = 0x40;<br>- break;<br>- case 0x500:<br>- set_x |= (1 << 18);<br>- rsize = 0x40;<br>- break;<br>- case 0x580:<br>- set_x |= (1 << 19);<br>- rsize = 0x40;<br>- break;<br>- case 0x4700:<br>- set_x |= (1 << 22);<br>- rsize = 0xc;<br>- break;<br>- case 0xfd60:<br>- set_x |= (1 << 23);<br>- rsize = 16;<br>- break;<br>- default:<br>- rsize = 0;<br>- /* try AGESA allocated region in region 0 */<br>- if ((var_num > 0) && ((base >= reg_var[0]) &&<br>- ((base + res->size) <= (reg_var[0] + reg_size[0]))))<br>- rsize = reg_size[0];<br>- }<br>- /* check if region found and matches the enable */<br>- if (res->size <= rsize) {<br>- reg |= set;<br>- reg_x |= set_x;<br>- /* check if we can fit resource in variable range */<br>- } else if ((var_num < 3) &&<br>- ((res->size <= 16) || (res->size == 512))) {<br>- /* use variable ranges if pre-defined do not match */<br>- switch (var_num) {<br>- case 0:<br>- reg_x |= (1 << 2);<br>- if (res->size <= 16)<br>- wiosize |= (1 << 0);<br>- break;<br>- case 1:<br>- reg_x |= (1 << 24);<br>- if (res->size <= 16)<br>- wiosize |= (1 << 2);<br>- break;<br>- case 2:<br>- reg_x |= (1 << 25);<br>- if (res->size <= 16)<br>- wiosize |= (1 << 3);<br>- break;<br>- }<br>- reg_var[var_num++] =<br>- base & 0xffff;<br>- } else {<br>- printk(BIOS_ERR, "cannot fit LPC decode region:%s, base=0x%08x, end=0x%08x\n",<br>- dev_path(child), base, end);<br>- }<br>- }<br>+ set_lpc_resource(child,<br>+ &var_num,<br>+ reg_var,<br>+ ®,<br>+ ®_x,<br>+ reg_size[0],<br>+ &wiosize);<br> }<br> }<br> }<br>- pci_write_config32(dev, 0x44, reg);<br>- pci_write_config32(dev, 0x48, reg_x);<br>+ pci_write_config32(dev, LPC_IO_PORT_DECODE_ENABLE, reg);<br>+ pci_write_config32(dev, LPC_IO_OR_MEM_DECODE_ENABLE, reg_x);<br> /* Set WideIO for as many IOs found (fall through is on purpose) */<br> switch (var_num) {<br> case 3:<br>- pci_write_config16(dev, 0x90, reg_var[2]);<br>+ pci_write_config16(dev, LPC_WIDEIO2_GENERIC_PORT, reg_var[2]);<br> /* fall through */<br> case 2:<br>- pci_write_config16(dev, 0x66, reg_var[1]);<br>+ pci_write_config16(dev, LPC_WIDEIO1_GENERIC_PORT, reg_var[1]);<br> /* fall through */<br> case 1:<br>- pci_write_config16(dev, 0x64, reg_var[0]);<br>+ pci_write_config16(dev, LPC_WIDEIO_GENERIC_PORT, reg_var[0]);<br> break;<br> }<br>- pci_write_config8(dev, 0x74, wiosize);<br>+ pci_write_config8(dev, LPC_ALT_WIDEIO_RANGE_ENABLE, wiosize);<br> }<br> <br> static void lpc_enable_resources(device_t dev)<br>diff --git a/src/soc/amd/stoneyridge/smbus_spd.c b/src/soc/amd/stoneyridge/smbus_spd.c<br>index 6669ccb..94deed5 100644<br>--- a/src/soc/amd/stoneyridge/smbus_spd.c<br>+++ b/src/soc/amd/stoneyridge/smbus_spd.c<br>@@ -21,6 +21,7 @@<br> #include <AGESA.h><br> #include <amdlib.h><br> #include <soc/southbridge.h><br>+#include <soc/smbus.h><br> #include <dimmSpd.h><br> <br> /*-----------------------------------------------------------------------------<br>@@ -34,28 +35,28 @@<br> <br> address |= 1; // set read bit<br> <br>- __outbyte(iobase + 0, 0xff); // clear error status<br>- __outbyte(iobase + 1, 0x1f); // clear error status<br>- __outbyte(iobase + 3, offset); // offset in eeprom<br>- __outbyte(iobase + 4, address); // slave address and read bit<br>- __outbyte(iobase + 2, 0x48); // read byte command<br>+ __outbyte(iobase + SMBHSTSTAT, SMBHST_STAT_CLEAR);<br>+ __outbyte(iobase + SMBSLVSTAT, SMBSLV_STAT_CLEAR);<br>+ __outbyte(iobase + SMBHSTCMD, offset); // offset in eeprom<br>+ __outbyte(iobase + SMBHSTADDR, address); // slave addr & read bit<br>+ __outbyte(iobase + SMBHSTCTRL, SMBHST_CTRL_STRT + SMBHST_CTRL_BDT_RW);<br> <br> // time limit to avoid hanging for unexpected error status<br> limit = __rdtsc() + 2000000000 / 10;<br> for (;;) {<br>- status = __inbyte(iobase);<br>+ status = __inbyte(iobase + SMBHSTSTAT);<br> if (__rdtsc() > limit)<br> break;<br>- if ((status & 2) == 0)<br>+ if ((status & SMBHST_STAT_INTERRUPT) == 0)<br> continue; // SMBusInterrupt not set, keep waiting<br>- if ((status & 1) == 1)<br>+ if ((status & SMBHST_STAT_BUSY) == SMBHST_STAT_BUSY)<br> continue; // HostBusy set, keep waiting<br> break;<br> }<br> <br>- buffer[0] = __inbyte(iobase + 5);<br>- if (status == 2)<br>- status = 0; // check for done with no errors<br>+ buffer[0] = __inbyte(iobase + SMBHSTDAT0);<br>+ if (status == SMBHST_STAT_NOERROR)<br>+ status = 0; // done with no errors<br> return status;<br> }<br> <br>@@ -69,25 +70,25 @@<br> unsigned int status;<br> UINT64 limit;<br> <br>- __outbyte(iobase + 0, 0xff); // clear error status<br>- __outbyte(iobase + 2, 0x44); // read command<br>+ __outbyte(iobase + SMBHSTSTAT, SMBHST_STAT_CLEAR);<br>+ __outbyte(iobase + SMBHSTCTRL, SMBHST_CTRL_STRT + SMBHST_CTRL_BTE_RW);<br> <br> // time limit to avoid hanging for unexpected error status<br> limit = __rdtsc() + 2000000000 / 10;<br> for (;;) {<br>- status = __inbyte(iobase);<br>+ status = __inbyte(iobase + SMBHSTSTAT);<br> if (__rdtsc() > limit)<br> break;<br>- if ((status & 2) == 0)<br>+ if ((status & SMBHST_STAT_INTERRUPT) == 0)<br> continue; // SMBusInterrupt not set, keep waiting<br>- if ((status & 1) == 1)<br>+ if ((status & SMBHST_STAT_BUSY) == SMBHST_STAT_BUSY)<br> continue; // HostBusy set, keep waiting<br> break;<br> }<br> <br>- buffer[0] = __inbyte(iobase + 5);<br>- if (status == 2)<br>- status = 0; // check for done with no errors<br>+ buffer[0] = __inbyte(iobase + SMBHSTDAT0);<br>+ if (status == SMBHST_STAT_NOERROR)<br>+ status = 0; // done with no errors<br> return status;<br> }<br> <br>@@ -138,15 +139,16 @@<br> <br> static void setupFch(int ioBase)<br> {<br>+ /* register 0x2c and 0x2d are not defined in public datasheet */<br> writePmReg(0x2d, ioBase >> 8);<br> writePmReg(0x2c, ioBase | 1);<br> /* set SMBus clock to 400 KHz */<br>- __outbyte(ioBase + 0x0e, 66000000 / 400000 / 4);<br>+ __outbyte(ioBase + SMBTIMING, 66000000 / 400000 / 4);<br> }<br> <br> int sb_readSpd(int spdAddress, char *buf, size_t len)<br> {<br>- int ioBase = 0xb00;<br>+ int ioBase = SMB_BASE_ADDR;<br> setupFch(ioBase);<br> return readspd(ioBase, spdAddress, buf, len);<br> }<br></pre><p>To view, visit <a href="https://review.coreboot.org/21767">change 21767</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/21767"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I9187ba1c41ebb1201ddc177e8184672c60cd5f5d </div>
<div style="display:none"> Gerrit-Change-Number: 21767 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Richard Spiegel <richard.spiegel@silverbackltd.com> </div>