diff options
Diffstat (limited to 'src/soc/amd')
-rw-r--r-- | src/soc/amd/stoneyridge/early_setup.c | 52 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/smbus.h | 73 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/southbridge.h | 84 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/lpc.c | 148 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/smbus_spd.c | 55 |
5 files changed, 268 insertions, 144 deletions
diff --git a/src/soc/amd/stoneyridge/early_setup.c b/src/soc/amd/stoneyridge/early_setup.c index b4e780ece1..ecae7ab62e 100644 --- a/src/soc/amd/stoneyridge/early_setup.c +++ b/src/soc/amd/stoneyridge/early_setup.c @@ -76,9 +76,9 @@ void sb_pci_port80(void) dev = PCI_DEV(0, PCU_DEV, LPC_FUNC); - byte = pci_read_config8(dev, 0x4a); - byte &= ~(1 << 5); /* disable lpc port 80 */ - pci_write_config8(dev, 0x4a, byte); + byte = pci_read_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH); + byte &= ~DECODE_IO_PORT_ENABLE4_H; /* disable lpc port 80 */ + pci_write_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH, byte); } void sb_lpc_port80(void) @@ -87,17 +87,17 @@ void sb_lpc_port80(void) pci_devfn_t dev; /* Enable LPC controller */ - outb(0xec, PM_INDEX); + outb(PM_LPC_GATING, PM_INDEX); byte = inb(PM_DATA); - byte |= 1; - outb(0xec, PM_INDEX); + byte |= PM_LPC_ENABLE; + outb(PM_LPC_GATING, PM_INDEX); outb(byte, PM_DATA); /* Enable port 80 LPC decode in pci function 3 configuration space. */ dev = PCI_DEV(0, PCU_DEV, LPC_FUNC); - byte = pci_read_config8(dev, 0x4a); - byte |= 1 << 5; /* enable port 80 */ - pci_write_config8(dev, 0x4a, byte); + byte = pci_read_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH); + byte |= DECODE_IO_PORT_ENABLE4_H; /* enable port 80 */ + pci_write_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH, byte); } void sb_lpc_decode(void) @@ -216,7 +216,7 @@ int s3_save_nvram_early(u32 dword, int size, int nvram_pos) printk(BIOS_DEBUG, "Writing %x of size %d to nvram pos: %d\n", dword, size, nvram_pos); - for (i = 0 ; i < size ; i++) { + for (i = 0; i < size; i++) { outb(nvram_pos, BIOSRAM_INDEX); outb((dword >> (8 * i)) & 0xff, BIOSRAM_DATA); nvram_pos++; @@ -229,7 +229,7 @@ int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos) { u32 data = *old_dword; int i; - for (i = 0 ; i < size ; i++) { + for (i = 0; i < size; i++) { outb(nvram_pos, BIOSRAM_INDEX); data &= ~(0xff << (i * 8)); data |= inb(BIOSRAM_DATA) << (i * 8); @@ -252,7 +252,7 @@ void sb_clk_output_48Mhz(void) ctrl = read32((void *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40)); /* clear the OSCOUT1_ClkOutputEnb to enable the 48 Mhz clock */ - ctrl &= ~(1<<2); + ctrl &= ~FCH_MISC_REG40_OSCOUT1_EN; write32((void *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40), ctrl); } @@ -336,29 +336,37 @@ void sb_enable_rom(void) dev = PCI_DEV(0, PCU_DEV, LPC_FUNC); - /* Decode variable LPC ROM address ranges 1 and 2. */ - reg8 = pci_io_read_config8(dev, 0x48); + /* + * Decode variable LPC ROM address ranges 1 and 2. + * Bits 3-4 are not defined in any publicly available datasheet + */ + reg8 = pci_io_read_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE); reg8 |= (1 << 3) | (1 << 4); - pci_io_write_config8(dev, 0x48, reg8); + pci_io_write_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE, reg8); + + /* + * LPC ROM address range 1: + * Enable LPC ROM range mirroring start at 0x000e(0000). + */ + pci_io_write_config16(dev, ROM_ADDRESS_RANGE1_START, 0x000e); - /* LPC ROM address range 1: */ - /* Enable LPC ROM range mirroring start at 0x000e(0000). */ - pci_io_write_config16(dev, 0x68, 0x000e); /* Enable LPC ROM range mirroring end at 0x000f(ffff). */ - pci_io_write_config16(dev, 0x6a, 0x000f); + pci_io_write_config16(dev, ROM_ADDRESS_RANGE1_END, 0x000f); - /* LPC ROM address range 2: */ /* + * LPC ROM address range 2: + * * Enable LPC ROM range start at: * 0xfff8(0000): 512KB * 0xfff0(0000): 1MB * 0xffe0(0000): 2MB * 0xffc0(0000): 4MB */ - pci_io_write_config16(dev, 0x6c, 0x10000 + pci_io_write_config16(dev, ROM_ADDRESS_RANGE2_START, 0x10000 - (CONFIG_COREBOOT_ROMSIZE_KB >> 6)); + /* Enable LPC ROM range end at 0xffff(ffff). */ - pci_io_write_config16(dev, 0x6e, 0xffff); + pci_io_write_config16(dev, ROM_ADDRESS_RANGE2_END, 0xffff); } void bootblock_fch_early_init(void) diff --git a/src/soc/amd/stoneyridge/include/soc/smbus.h b/src/soc/amd/stoneyridge/include/soc/smbus.h index 90a59e4743..1ec4e48277 100644 --- a/src/soc/amd/stoneyridge/include/soc/smbus.h +++ b/src/soc/amd/stoneyridge/include/soc/smbus.h @@ -18,30 +18,61 @@ #include <stdint.h> -#define SMBHSTSTAT 0x0 -#define SMBSLVSTAT 0x1 -#define SMBHSTCTRL 0x2 -#define SMBHSTCMD 0x3 -#define SMBHSTADDR 0x4 -#define SMBHSTDAT0 0x5 -#define SMBHSTDAT1 0x6 -#define SMBHSTBLKDAT 0x7 -#define SMBSLVCTRL 0x8 -#define SMBSLVCMD_SHADOW 0x9 -#define SMBSLVEVT 0xa -#define SMBSLVDAT 0xc +#define SMBHSTSTAT 0x0 +#define SMBHST_STAT_FAILED 0x10 +#define SMBHST_STAT_COLLISION 0x08 +#define SMBHST_STAT_ERROR 0x04 +#define SMBHST_STAT_INTERRUPT 0x02 +#define SMBHST_STAT_BUSY 0x01 +#define SMBHST_STAT_CLEAR 0xff +#define SMBHST_STAT_NOERROR 0x02 -#define AX_INDXC 0 -#define AX_INDXP 2 -#define AXCFG 4 -#define ABCFG 6 -#define RC_INDXC 1 -#define RC_INDXP 3 +#define SMBSLVSTAT 0x1 +#define SMBSLV_STAT_ALERT 0x20 +#define SMBSLV_STAT_SHADOW2 0x10 +#define SMBSLV_STAT_SHADOW1 0x08 +#define SMBSLV_STAT_SLV_STS 0x04 +#define SMBSLV_STAT_SLV_INIT 0x02 +#define SMBSLV_STAT_SLV_BUSY 0x01 +#define SMBSLV_STAT_CLEAR 0x1f -#define AB_INDX 0xcd8 -#define AB_DATA (AB_INDX+4) +#define SMBHSTCTRL 0x2 +#define SMBHST_CTRL_RST 0x80 +#define SMBHST_CTRL_STRT 0x40 +#define SMBHST_CTRL_QCK_RW 0x00 +#define SMBHST_CTRL_BTE_RW 0x04 +#define SMBHST_CTRL_BDT_RW 0x08 +#define SMBHST_CTRL_WDT_RW 0x0c +#define SMBHST_CTRL_BLK_RW 0x14 +#define SMBHST_CTRL_MODE_BITS 0x1c +#define SMBHST_CTRL_KILL 0x02 +#define SMBHST_CTRL_IEN 0x01 -/* Between 1-10 seconds, We should never timeout normally +#define SMBHSTCMD 0x3 +#define SMBHSTADDR 0x4 +#define SMBHSTDAT0 0x5 +#define SMBHSTDAT1 0x6 +#define SMBHSTBLKDAT 0x7 +#define SMBSLVCTRL 0x8 +#define SMBSLVCMD_SHADOW 0x9 +#define SMBSLVEVT 0xa +#define SMBSLVDAT 0xc +#define SMBTIMING 0xe + +#define SMB_BASE_ADDR 0xb00 + +#define AX_INDXC 0 +#define AX_INDXP 2 +#define AXCFG 4 +#define ABCFG 6 +#define RC_INDXC 1 +#define RC_INDXP 3 + +#define AB_INDX 0xcd8 +#define AB_DATA (AB_INDX+4) + +/* + * Between 1-10 seconds, We should never timeout normally * Longer than this is just painful when a timeout condition occurs. */ #define SMBUS_TIMEOUT (100 * 1000 * 10) diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index d506af979a..8e04b68ab2 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -28,6 +28,11 @@ /* Offsets from ACPI_MMIO_BASE */ #define APU_SMI_BASE 0xfed80200 +/* + * Offsets from ACPI_MMIO_BASE + * This is defined by AGESA, but we don't include AGESA headers to avoid + * polluting the namespace. + */ #define PM_MMIO_BASE 0xfed80300 #define APU_UART0_BASE 0xfedc6000 @@ -46,6 +51,17 @@ #define FORCE_STPCLK_RETRY BIT(24) #define PM_ACPI_MMIO_EN 0x24 #define PM_SERIRQ_CONF 0x54 +#define PM_SERIRQ_NUM_BITS_17 0x0000 +#define PM_SERIRQ_NUM_BITS_18 0x0004 +#define PM_SERIRQ_NUM_BITS_19 0x0008 +#define PM_SERIRQ_NUM_BITS_20 0x000c +#define PM_SERIRQ_NUM_BITS_21 0x0010 +#define PM_SERIRQ_NUM_BITS_22 0x0014 +#define PM_SERIRQ_NUM_BITS_23 0x0018 +#define PM_SERIRQ_NUM_BITS_24 0x001c +#define PM_SERIRQ_MODE BIT(6) +#define PM_SERIRQ_ENABLE BIT(7) + #define PM_EVT_BLK 0x60 #define PM1_CNT_BLK 0x62 #define PM_TMR_BLK 0x64 @@ -60,6 +76,10 @@ #define PM_HUD_SD_FLASH_CTRL 0xe7 #define PM_YANG_SD_FLASH_CTRL 0xe8 #define PM_PCIB_CFG 0xea +#define PM_LPC_GATING 0xec +#define PM_LPC_AB_NO_BYPASS_EN BIT(2) +#define PM_LPC_A20_EN BIT(1) +#define PM_LPC_ENABLE BIT(0) #define SYS_RESET 0xcf9 @@ -70,14 +90,27 @@ #define ACPI_GPE0_BLK (STONEYRIDGE_ACPI_IO_BASE + 0x10) /* 8 bytes */ #define ACPI_CPU_CONTROL (STONEYRIDGE_ACPI_IO_BASE + 0x08) /* 6 bytes */ -#define REV_STONEYRIDGE_A11 0x11 -#define REV_STONEYRIDGE_A12 0x12 +#define ACPI_SMI_CTL_PORT 0xb2 +#define ACPI_SMI_CMD_CST_CONTROL 0xde +#define ACPI_SMI_CMD_PST_CONTROL 0xad +#define ACPI_SMI_CMD_DISABLE 0xbe +#define ACPI_SMI_CMD_ENABLE 0xef +#define ACPI_SMI_CMD_S4_REQ 0xc0 + +#define REV_STONEYRIDGE_A11 0x11 +#define REV_STONEYRIDGE_A12 0x12 #define SPIROM_BASE_ADDRESS_REGISTER 0xa0 #define ROUTE_TPM_2_SPI BIT(3) -#define SPI_ROM_ENABLE 0x02 +#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)) #define SPI_BASE_ADDRESS 0xfec10000 +#define LPC_PCI_CONTROL 0x40 +#define LEGACY_DMA_EN BIT(2) + #define LPC_IO_PORT_DECODE_ENABLE 0x44 #define DECODE_ENABLE_PARALLEL_PORT0 BIT(0) #define DECODE_ENABLE_PARALLEL_PORT1 BIT(1) @@ -115,17 +148,58 @@ #define LPC_IO_OR_MEM_DECODE_ENABLE 0x48 #define LPC_WIDEIO2_ENABLE BIT(25) #define LPC_WIDEIO1_ENABLE BIT(24) +#define DECODE_IO_PORT_ENABLE6 BIT(23) +#define DECODE_IO_PORT_ENABLE5 BIT(22) +#define DECODE_IO_PORT_ENABLE4 BIT(21) +#define DECODE_IO_PORT_ENABLE3 BIT(19) +#define DECODE_IO_PORT_ENABLE2 BIT(18) +#define DECODE_IO_PORT_ENABLE1 BIT(17) +#define DECODE_IO_PORT_ENABLE0 BIT(16) +#define LPC_SYNC_TIMEOUT_COUNT_ENABLE BIT(7) #define LPC_WIDEIO0_ENABLE BIT(2) +/* Assuming word access to higher word (register 0x4a) */ +#define LPC_IO_OR_MEM_DEC_EN_HIGH 0x4a +#define LPC_WIDEIO2_ENABLE_H BIT(9) +#define LPC_WIDEIO1_ENABLE_H BIT(8) +#define DECODE_IO_PORT_ENABLE6_H BIT(7) +#define DECODE_IO_PORT_ENABLE5_H BIT(6) +#define DECODE_IO_PORT_ENABLE4_H BIT(5) +#define DECODE_IO_PORT_ENABLE3_H BIT(3) +#define DECODE_IO_PORT_ENABLE2_H BIT(2) +#define DECODE_IO_PORT_ENABLE1_H BIT(1) +#define DECODE_IO_PORT_ENABLE0_H BIT(0) +/* + * Register 0x64 is 32-bit, composed by two 16-bit sub-registers. + * For ease of access, each sub-register is declared separetely. + */ #define LPC_WIDEIO_GENERIC_PORT 0x64 +#define LPC_WIDEIO1_GENERIC_PORT 0x66 +#define ROM_ADDRESS_RANGE1_START 0x68 +#define ROM_ADDRESS_RANGE1_END 0x6a +#define ROM_ADDRESS_RANGE2_START 0x6c +#define ROM_ADDRESS_RANGE2_END 0x6e #define LPC_ALT_WIDEIO_RANGE_ENABLE 0x74 #define LPC_ALT_WIDEIO2_ENABLE BIT(3) #define LPC_ALT_WIDEIO1_ENABLE BIT(2) #define LPC_ALT_WIDEIO0_ENABLE BIT(0) +#define LPC_MISC_CONTROL_BITS 0x78 +#define LPC_NOHOG BIT(0) + #define LPC_WIDEIO2_GENERIC_PORT 0x90 +/* + * LPC register 0xb8 is DWORD, here there are definitions for byte + * access. For example, bits 31-24 are accessed through byte access + * at register 0xbb (). + */ +#define LPC_ROM_DMA_EC_HOST_CONTROL 0xb8 + +#define LPC_HOST_CONTROL 0xbb +#define SPI_FROM_HOST_PREFETCH_EN BIT(0) + #define SPI_CNTRL0 0x00 #define SPI_READ_MODE_MASK (BIT(30) | BIT(29) | BIT(18)) /* Nominal is 16.7MHz on older devices, 33MHz on newer */ @@ -162,6 +236,10 @@ #define SPI100_HOST_PREF_CONFIG 0x2c #define SPI_RD4DW_EN_HOST BIT(15) +#define FCH_MISC_REG40_OSCOUT1_EN BIT(2) + +#define FLASH_BASE_ADDR ((0xffffffff - CONFIG_ROM_SIZE) + 1) + static inline int sb_sata_enable(void) { /* True if IDE or AHCI. */ diff --git a/src/soc/amd/stoneyridge/lpc.c b/src/soc/amd/stoneyridge/lpc.c index a67d06ae3e..8206950a0b 100644 --- a/src/soc/amd/stoneyridge/lpc.c +++ b/src/soc/amd/stoneyridge/lpc.c @@ -40,7 +40,10 @@ static void lpc_init(device_t dev) u32 dword; device_t sm_dev; - /* Enable the LPC Controller */ + /* + * Enable the LPC Controller + * SMBus register 0x64 is not defined in public datasheet. + */ sm_dev = dev_find_slot(0, PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC)); dword = pci_read_config32(sm_dev, 0x64); dword |= 1 << 20; @@ -50,37 +53,40 @@ static void lpc_init(device_t dev) isa_dma_init(); /* Enable DMA transaction on the LPC bus */ - byte = pci_read_config8(dev, 0x40); - byte |= (1 << 2); - pci_write_config8(dev, 0x40, byte); + byte = pci_read_config8(dev, LPC_PCI_CONTROL); + byte |= LEGACY_DMA_EN; + pci_write_config8(dev, LPC_PCI_CONTROL, byte); /* Disable the timeout mechanism on LPC */ - byte = pci_read_config8(dev, 0x48); - byte &= ~(1 << 7); - pci_write_config8(dev, 0x48, byte); + byte = pci_read_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE); + byte &= ~LPC_SYNC_TIMEOUT_COUNT_ENABLE; + pci_write_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE, byte); /* Disable LPC MSI Capability */ - byte = pci_read_config8(dev, 0x78); + byte = pci_read_config8(dev, LPC_MISC_CONTROL_BITS); + /* BIT 1 is not defined in public datasheet. */ byte &= ~(1 << 1); - /* Keep the old way. i.e., when bus master/DMA cycle is going + + /* + * Keep the old way. i.e., when bus master/DMA cycle is going * on on LPC, it holds PCI grant, so no LPC slave cycle can * interrupt and visit LPC. */ - byte &= ~(1 << 0); - pci_write_config8(dev, 0x78, byte); + byte &= ~LPC_NOHOG; + pci_write_config8(dev, LPC_MISC_CONTROL_BITS, byte); - /* bit0: Enable prefetch a cacheline (64 bytes) when Host reads - * code from SPI ROM + /* * bit3: Fix SPI_CS# timing issue when running at 66M. TODO:A12. - * todo: verify both these against BKDG + * todo: verify against BKDG */ - byte = pci_read_config8(dev, 0xbb); - byte |= 1 << 0 | 1 << 3; - pci_write_config8(dev, 0xbb, byte); + byte = pci_read_config8(dev, LPC_HOST_CONTROL); + byte |= SPI_FROM_HOST_PREFETCH_EN | 1 << 3; + pci_write_config8(dev, LPC_HOST_CONTROL, byte); cmos_check_update_date(); - /* Initialize the real time clock. + /* + * Initialize the real time clock. * The 0 argument tells cmos_init not to * update CMOS unless it is invalid. * 1 tells cmos_init to always initialize the CMOS. @@ -94,9 +100,9 @@ static void lpc_init(device_t dev) setup_i8254(); /* Set up SERIRQ, enable continuous mode */ - byte = (BIT(4) | BIT(7)); + byte = (PM_SERIRQ_NUM_BITS_21 | PM_SERIRQ_ENABLE); if (!IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE)) - byte |= BIT(6); + byte |= PM_SERIRQ_MODE; pm_write8(PM_SERIRQ_CONF, byte); } @@ -117,8 +123,8 @@ static void lpc_read_resources(device_t dev) IORESOURCE_ASSIGNED | IORESOURCE_FIXED; res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0)); - res->base = 0xff800000; - res->size = 0x00800000; /* 8 MB for flash */ + res->base = FLASH_BASE_ADDR; + res->size = CONFIG_ROM_SIZE; res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; @@ -145,7 +151,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 &= 0xf; + spi_enable_bits &= SPI_PRESERVE_BITS; pci_write_config32(dev, SPIROM_BASE_ADDRESS_REGISTER, res->base | spi_enable_bits); @@ -171,71 +177,72 @@ static void set_lpc_resource(device_t child, continue; base = res->base; end = resource_end(res); - /* find a resource size */ printk(BIOS_DEBUG, - "Southbridge LPC decode:%s, base=0x%08x, end=0x%08x\n", - dev_path(child), base, end); + "Southbridge LPC decode:%s, base=0x%08x, end=0x%08x\n", + dev_path(child), base, end); + /* find a resource size */ switch (base) { case 0x60: /* KB */ case 0x64: /* MS */ - set |= (1 << 29); + set |= DECODE_ENABLE_KBC_PORT; rsize = 1; break; case 0x3f8: /* COM1 */ - set |= (1 << 6); + set |= DECODE_ENABLE_SERIAL_PORT0; rsize = 8; break; case 0x2f8: /* COM2 */ - set |= (1 << 7); + set |= DECODE_ENABLE_SERIAL_PORT1; rsize = 8; break; case 0x378: /* Parallel 1 */ - set |= (1 << 0); - set |= (1 << 1); /* + 0x778 for ECP */ + set |= DECODE_ENABLE_PARALLEL_PORT0; + /* enable 0x778 for ECP mode */ + set |= DECODE_ENABLE_PARALLEL_PORT1; rsize = 8; break; case 0x3f0: /* FD0 */ - set |= (1 << 26); + set |= DECODE_ENABLE_FDC_PORT0; rsize = 8; break; case 0x220: /* 0x220 - 0x227 */ - set |= (1 << 8); + set |= DECODE_ENABLE_SERIAL_PORT2; rsize = 8; break; case 0x228: /* 0x228 - 0x22f */ - set |= (1 << 9); + set |= DECODE_ENABLE_SERIAL_PORT3; rsize = 8; break; case 0x238: /* 0x238 - 0x23f */ - set |= (1 << 10); + set |= DECODE_ENABLE_SERIAL_PORT4; rsize = 8; break; case 0x300: /* 0x300 - 0x301 */ - set |= (1 << 18); + set |= DECODE_ENABLE_MIDI_PORT0; rsize = 2; break; case 0x400: - set_x |= (1 << 16); + set_x |= DECODE_IO_PORT_ENABLE0; rsize = 0x40; break; case 0x480: - set_x |= (1 << 17); + set_x |= DECODE_IO_PORT_ENABLE1; rsize = 0x40; break; case 0x500: - set_x |= (1 << 18); + set_x |= DECODE_IO_PORT_ENABLE2; rsize = 0x40; break; case 0x580: - set_x |= (1 << 19); + set_x |= DECODE_IO_PORT_ENABLE3; rsize = 0x40; break; case 0x4700: - set_x |= (1 << 22); + set_x |= DECODE_IO_PORT_ENABLE5; rsize = 0xc; break; case 0xfd60: - set_x |= (1 << 23); + set_x |= DECODE_IO_PORT_ENABLE6; rsize = 16; break; default: @@ -250,30 +257,30 @@ static void set_lpc_resource(device_t child, *reg |= set; *reg_x |= set_x; /* check if we can fit resource in variable range */ - } else if ((var_num < 3) && ((res->size <= 16) || - (res->size == 512))) { + } else if ((var_num < 3) && + ((res->size <= 16) || (res->size == 512))) { /* use variable ranges if pre-defined do not match */ switch (var_num) { case 0: - *reg_x |= (1 << 2); + *reg_x |= LPC_WIDEIO0_ENABLE; if (res->size <= 16) - *wiosize |= (1 << 0); + *wiosize |= LPC_ALT_WIDEIO0_ENABLE; break; case 1: - *reg_x |= (1 << 24); + *reg_x |= LPC_WIDEIO1_ENABLE; if (res->size <= 16) - *wiosize |= (1 << 2); + *wiosize |= LPC_ALT_WIDEIO1_ENABLE; break; case 2: - *reg_x |= (1 << 25); + *reg_x |= LPC_WIDEIO2_ENABLE; if (res->size <= 16) - *wiosize |= (1 << 3); + *wiosize |= LPC_ALT_WIDEIO2_ENABLE; break; } - reg_var[var_num++] = - base & 0xffff; + reg_var[var_num++] = base & 0xffff; } else { - printk(BIOS_ERR, "cannot fit LPC decode region:"); + printk(BIOS_ERR, + "cannot fit LPC decode region:"); printk(BIOS_ERR, "%s, base = 0x%08x, end = 0x%08x\n", dev_path(child), base, end); } @@ -294,9 +301,10 @@ static void lpc_enable_childrens_resources(device_t dev) int var_num = 0; u16 reg_var[3]; u16 reg_size[1] = {512}; - u8 wiosize = pci_read_config8(dev, 0x74); + u8 wiosize = pci_read_config8(dev, LPC_ALT_WIDEIO_RANGE_ENABLE); - /* Be a bit relaxed, tolerate that LPC region might be bigger than + /* + * Be a bit relaxed, tolerate that LPC region might be bigger than * resource we try to fit, do it like this for all regions < 16 bytes. * If there is a resource > 16 bytes it must be 512 bytes to be able * to allocate the fresh LPC window. @@ -306,26 +314,26 @@ static void lpc_enable_childrens_resources(device_t dev) * The code tries to check if resource can fit into this region. */ - reg = pci_read_config32(dev, 0x44); - reg_x = pci_read_config32(dev, 0x48); + reg = pci_read_config32(dev, LPC_IO_PORT_DECODE_ENABLE); + reg_x = pci_read_config32(dev, LPC_IO_OR_MEM_DECODE_ENABLE); /* check if ranges are free and don't use them if already taken */ - if (reg_x & (1 << 2)) + if (reg_x & LPC_WIDEIO0_ENABLE) var_num = 1; /* just in case check if someone did not manually set other ranges */ - if (reg_x & (1 << 24)) + if (reg_x & LPC_WIDEIO1_ENABLE) var_num = 2; - if (reg_x & (1 << 25)) + if (reg_x & LPC_WIDEIO2_ENABLE) var_num = 3; /* check AGESA region size */ - if (wiosize & (1 << 0)) + if (wiosize & LPC_ALT_WIDEIO0_ENABLE) reg_size[0] = 16; - reg_var[2] = pci_read_config16(dev, 0x90); - reg_var[1] = pci_read_config16(dev, 0x66); - reg_var[0] = pci_read_config16(dev, 0x64); + reg_var[2] = pci_read_config16(dev, LPC_WIDEIO2_GENERIC_PORT); + reg_var[1] = pci_read_config16(dev, LPC_WIDEIO1_GENERIC_PORT); + reg_var[0] = pci_read_config16(dev, LPC_WIDEIO_GENERIC_PORT); /* todo: clean up the code style here */ for (link = dev->link_list; link; link = link->next) { @@ -344,21 +352,21 @@ static void lpc_enable_childrens_resources(device_t dev) } } } - pci_write_config32(dev, 0x44, reg); - pci_write_config32(dev, 0x48, reg_x); + pci_write_config32(dev, LPC_IO_PORT_DECODE_ENABLE, reg); + pci_write_config32(dev, LPC_IO_OR_MEM_DECODE_ENABLE, reg_x); /* Set WideIO for as many IOs found (fall through is on purpose) */ switch (var_num) { case 3: - pci_write_config16(dev, 0x90, reg_var[2]); + pci_write_config16(dev, LPC_WIDEIO2_GENERIC_PORT, reg_var[2]); /* fall through */ case 2: - pci_write_config16(dev, 0x66, reg_var[1]); + pci_write_config16(dev, LPC_WIDEIO1_GENERIC_PORT, reg_var[1]); /* fall through */ case 1: - pci_write_config16(dev, 0x64, reg_var[0]); + pci_write_config16(dev, LPC_WIDEIO_GENERIC_PORT, reg_var[0]); break; } - pci_write_config8(dev, 0x74, wiosize); + pci_write_config8(dev, LPC_ALT_WIDEIO_RANGE_ENABLE, wiosize); } static void lpc_enable_resources(device_t dev) diff --git a/src/soc/amd/stoneyridge/smbus_spd.c b/src/soc/amd/stoneyridge/smbus_spd.c index 9bbce5bc25..605f8da78e 100644 --- a/src/soc/amd/stoneyridge/smbus_spd.c +++ b/src/soc/amd/stoneyridge/smbus_spd.c @@ -20,10 +20,10 @@ #include <Porting.h> #include <AGESA.h> #include <soc/southbridge.h> +#include <soc/smbus.h> #include <dimmSpd.h> -/*----------------------------------------------------------------------------- - * +/* * readSmbusByteData - read a single SPD byte from any offset */ static int readSmbusByteData(int iobase, int address, char *buffer, int offset) @@ -33,33 +33,32 @@ static int readSmbusByteData(int iobase, int address, char *buffer, int offset) address |= 1; // set read bit - __outbyte(iobase + 0, 0xff); // clear error status - __outbyte(iobase + 1, 0x1f); // clear error status - __outbyte(iobase + 3, offset); // offset in eeprom - __outbyte(iobase + 4, address); // slave address and read bit - __outbyte(iobase + 2, 0x48); // read byte command + __outbyte(iobase + SMBHSTSTAT, SMBHST_STAT_CLEAR); + __outbyte(iobase + SMBSLVSTAT, SMBSLV_STAT_CLEAR); + __outbyte(iobase + SMBHSTCMD, offset); // offset in eeprom + __outbyte(iobase + SMBHSTADDR, address); // slave addr & read bit + __outbyte(iobase + SMBHSTCTRL, SMBHST_CTRL_STRT + SMBHST_CTRL_BDT_RW); // time limit to avoid hanging for unexpected error status limit = __rdtsc() + 2000000000 / 10; for (;;) { - status = __inbyte(iobase); + status = __inbyte(iobase + SMBHSTSTAT); if (__rdtsc() > limit) break; - if ((status & 2) == 0) + if ((status & SMBHST_STAT_INTERRUPT) == 0) continue; // SMBusInterrupt not set, keep waiting - if ((status & 1) == 1) + if ((status & SMBHST_STAT_BUSY) == SMBHST_STAT_BUSY) continue; // HostBusy set, keep waiting break; } - buffer[0] = __inbyte(iobase + 5); - if (status == 2) - status = 0; // check for done with no errors + buffer[0] = __inbyte(iobase + SMBHSTDAT0); + if (status == SMBHST_STAT_NOERROR) + status = 0; // done with no errors return status; } -/*----------------------------------------------------------------------------- - * +/* * readSmbusByte - read a single SPD byte from the default offset * this function is faster function readSmbusByteData */ @@ -68,30 +67,29 @@ static int readSmbusByte(int iobase, int address, char *buffer) unsigned int status; UINT64 limit; - __outbyte(iobase + 0, 0xff); // clear error status - __outbyte(iobase + 2, 0x44); // read command + __outbyte(iobase + SMBHSTSTAT, SMBHST_STAT_CLEAR); + __outbyte(iobase + SMBHSTCTRL, SMBHST_CTRL_STRT + SMBHST_CTRL_BTE_RW); // time limit to avoid hanging for unexpected error status limit = __rdtsc() + 2000000000 / 10; for (;;) { - status = __inbyte(iobase); + status = __inbyte(iobase + SMBHSTSTAT); if (__rdtsc() > limit) break; - if ((status & 2) == 0) + if ((status & SMBHST_STAT_INTERRUPT) == 0) continue; // SMBusInterrupt not set, keep waiting - if ((status & 1) == 1) + if ((status & SMBHST_STAT_BUSY) == SMBHST_STAT_BUSY) continue; // HostBusy set, keep waiting break; } - buffer[0] = __inbyte(iobase + 5); - if (status == 2) - status = 0; // check for done with no errors + buffer[0] = __inbyte(iobase + SMBHSTDAT0); + if (status == SMBHST_STAT_NOERROR) + status = 0; // done with no errors return status; } -/*--------------------------------------------------------------------------- - * +/* * readspd - Read one or more SPD bytes from a DIMM. * Start with offset zero and read sequentially. * Optimization relies on autoincrement to avoid @@ -115,7 +113,7 @@ static int readspd(int iobase, int SmbusSlaveAddress, char *buffer, int count) } /* read the remaining bytes using auto-increment for speed */ - for (index = 1 ; index < count ; index++) { + for (index = 1; index < count; index++) { error = readSmbusByte(iobase, SmbusSlaveAddress, &buffer[index]); if (error) { @@ -137,15 +135,16 @@ static void writePmReg(int reg, int data) static void setupFch(int ioBase) { + /* register 0x2c and 0x2d are not defined in public datasheet */ writePmReg(0x2d, ioBase >> 8); writePmReg(0x2c, ioBase | 1); /* set SMBus clock to 400 KHz */ - __outbyte(ioBase + 0x0e, 66000000 / 400000 / 4); + __outbyte(ioBase + SMBTIMING, 66000000 / 400000 / 4); } int sb_readSpd(int spdAddress, char *buf, size_t len) { - int ioBase = 0xb00; + int ioBase = SMB_BASE_ADDR; setupFch(ioBase); return readspd(ioBase, spdAddress, buf, len); } |