<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>+                                             &reg,<br>+                                            &reg_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>