diff options
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/iomap.h | 2 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/smbus.h | 52 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/southbridge.h | 48 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/sb_util.c | 10 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/sm.c | 39 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/smbus.c | 73 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/smbus_spd.c | 30 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/southbridge.c | 13 |
8 files changed, 134 insertions, 133 deletions
diff --git a/src/soc/amd/stoneyridge/include/soc/iomap.h b/src/soc/amd/stoneyridge/include/soc/iomap.h index 78e8e090a3..b1010142ef 100644 --- a/src/soc/amd/stoneyridge/include/soc/iomap.h +++ b/src/soc/amd/stoneyridge/include/soc/iomap.h @@ -38,6 +38,8 @@ #define PM_MMIO_BASE 0xfed80300 #define BIOSRAM_MMIO_BASE 0xfed80500 #define ACPI_REG_MMIO_BASE 0xfed80800 +#define ASF_MMIO_BASE 0xfed80900 +#define SMBUS_MMIO_BASE 0xfed80a00 #define GPIO_IOMUX_MMIO_BASE 0xfed80d00 #define MISC_MMIO_BASE 0xfed80e00 #define XHCI_ACPI_PM_MMIO_BASE 0xfed81c00 diff --git a/src/soc/amd/stoneyridge/include/soc/smbus.h b/src/soc/amd/stoneyridge/include/soc/smbus.h index 1bb4346186..71f7fafa5e 100644 --- a/src/soc/amd/stoneyridge/include/soc/smbus.h +++ b/src/soc/amd/stoneyridge/include/soc/smbus.h @@ -19,50 +19,6 @@ #include <stdint.h> #include <soc/iomap.h> -#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 SMBHST_STAT_VAL_BITS 0x1f -#define SMBHST_STAT_ERROR_BITS 0x1c - -#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 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 - -#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_ASF_IO_BASE 0x01 #define SMB_SPEED_400KHZ (66000000 / (400000 * 4)) #define AX_INDXC 0 @@ -91,10 +47,10 @@ #define rcindxp_reg(reg, port, mask, val) \ alink_rc_indx((RC_INDXP), (reg), (port), (mask), (val)) -int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address); -int do_smbus_write_byte(u16 smbus_io_base, u8 device, u8 address, u8 val); -int do_smbus_recv_byte(u16 smbus_io_base, u8 device); -int do_smbus_send_byte(u16 smbus_io_base, u8 device, u8 val); +int do_smbus_read_byte(u32 mmio, u8 device, u8 address); +int do_smbus_write_byte(u32 mmio, u8 device, u8 address, u8 val); +int do_smbus_recv_byte(u32 mmio, u8 device); +int do_smbus_send_byte(u32 mmio, u8 device, u8 val); void alink_rc_indx(u32 reg_space, u32 reg_addr, u32 port, u32 mask, u32 val); void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val); void alink_ax_indx(u32 space /*c or p? */, u32 axindc, u32 mask, u32 val); diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index adf3af243d..1652bbc56f 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -39,6 +39,8 @@ #define FORCE_SLPSTATE_RETRY BIT(25) #define FORCE_STPCLK_RETRY BIT(24) +#define SMB_ASF_IO_BASE 0x01 /* part of PM_DECODE_EN */ + #define PWR_RESET_CFG 0x10 #define TOGGLE_ALL_PWR_GOOD BIT(1) @@ -111,6 +113,50 @@ #define MMIO_ACPI_GPE0_EN 0x18 #define MMIO_ACPI_PM_TMR_BLK 0x08 +/* SMBUS MMIO offsets 0xfed80a00 */ +#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 SMBHST_STAT_VAL_BITS 0x1f +#define SMBHST_STAT_ERROR_BITS 0x1c + +#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 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 + +#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 + /* FCH MISC Registers 0xfed80e00 */ #define GPP_CLK_CNTRL 0x00 #define GPP_CLK2_REQ_MAP_SHIFT 8 @@ -480,6 +526,8 @@ void xhci_pm_write16(uint8_t reg, uint16_t value); uint16_t xhci_pm_read16(uint8_t reg); void xhci_pm_write32(uint8_t reg, uint32_t value); uint32_t xhci_pm_read32(uint8_t reg); +void smbus_write8(uint32_t mmio, uint8_t reg, uint8_t value); +uint8_t smbus_read8(uint32_t mmio, uint8_t reg); void bootblock_fch_early_init(void); void bootblock_fch_init(void); /** diff --git a/src/soc/amd/stoneyridge/sb_util.c b/src/soc/amd/stoneyridge/sb_util.c index ccbde7e5d9..eeb550cb7f 100644 --- a/src/soc/amd/stoneyridge/sb_util.c +++ b/src/soc/amd/stoneyridge/sb_util.c @@ -200,6 +200,16 @@ uint32_t xhci_pm_read32(uint8_t reg) return read32((void *)(XHCI_ACPI_PM_MMIO_BASE + reg)); } +void smbus_write8(uint32_t mmio, uint8_t reg, uint8_t value) +{ + write8((void *)(mmio + reg), value); +} + +uint8_t smbus_read8(uint32_t mmio, uint8_t reg) +{ + return read8((void *)(mmio + reg)); +} + int acpi_get_sleep_type(void) { return acpi_sleep_from_pm1(inw(pm_acpi_pm_cnt_blk())); diff --git a/src/soc/amd/stoneyridge/sm.c b/src/soc/amd/stoneyridge/sm.c index 22cbde8854..82c265e475 100644 --- a/src/soc/amd/stoneyridge/sm.c +++ b/src/soc/amd/stoneyridge/sm.c @@ -35,60 +35,49 @@ static void sm_init(struct device *dev) setup_ioapic(VIO_APIC_VADDR, CONFIG_MAX_CPUS); } -static int lsmbus_recv_byte(struct device *dev) +static u32 get_sm_mmio(struct device *dev) { - u8 device; struct resource *res; struct bus *pbus; - device = dev->path.i2c.device; pbus = get_pbus_smbus(dev); - res = find_resource(pbus->dev, 0x90); + if (res->base == SMB_BASE_ADDR) + return SMBUS_MMIO_BASE; - return do_smbus_recv_byte(res->base, device); + return ASF_MMIO_BASE; } -static int lsmbus_send_byte(struct device *dev, u8 val) +static int lsmbus_recv_byte(struct device *dev) { u8 device; - struct resource *res; - struct bus *pbus; device = dev->path.i2c.device; - pbus = get_pbus_smbus(dev); + return do_smbus_recv_byte(get_sm_mmio(dev), device); +} - res = find_resource(pbus->dev, 0x90); +static int lsmbus_send_byte(struct device *dev, u8 val) +{ + u8 device; - return do_smbus_send_byte(res->base, device, val); + device = dev->path.i2c.device; + return do_smbus_send_byte(get_sm_mmio(dev), device, val); } static int lsmbus_read_byte(struct device *dev, u8 address) { u8 device; - struct resource *res; - struct bus *pbus; device = dev->path.i2c.device; - pbus = get_pbus_smbus(dev); - - res = find_resource(pbus->dev, 0x90); - - return do_smbus_read_byte(res->base, device, address); + return do_smbus_read_byte(get_sm_mmio(dev), device, address); } static int lsmbus_write_byte(struct device *dev, u8 address, u8 val) { u8 device; - struct resource *res; - struct bus *pbus; device = dev->path.i2c.device; - pbus = get_pbus_smbus(dev); - - res = find_resource(pbus->dev, 0x90); - - return do_smbus_write_byte(res->base, device, address, val); + return do_smbus_write_byte(get_sm_mmio(dev), device, address, val); } static struct smbus_bus_operations lops_smbus_bus = { .recv_byte = lsmbus_recv_byte, diff --git a/src/soc/amd/stoneyridge/smbus.c b/src/soc/amd/stoneyridge/smbus.c index 919a52edd4..21750d8be9 100644 --- a/src/soc/amd/stoneyridge/smbus.c +++ b/src/soc/amd/stoneyridge/smbus.c @@ -16,143 +16,144 @@ #include <io.h> #include <stdint.h> #include <soc/smbus.h> +#include <soc/southbridge.h> -static int smbus_wait_until_ready(u16 smbus_io_base) +static int smbus_wait_until_ready(u32 mmio) { u32 loops; loops = SMBUS_TIMEOUT; do { u8 val; - val = inb(smbus_io_base + SMBHSTSTAT); + val = smbus_read8(mmio, SMBHSTSTAT); val &= SMBHST_STAT_VAL_BITS; if (val == 0) { /* ready now */ return 0; } - outb(val, smbus_io_base + SMBHSTSTAT); + smbus_write8(mmio, SMBHSTSTAT, val); } while (--loops); return -2; /* time out */ } -static int smbus_wait_until_done(u16 smbus_io_base) +static int smbus_wait_until_done(u32 mmio) { u32 loops; loops = SMBUS_TIMEOUT; do { u8 val; - val = inb(smbus_io_base + SMBHSTSTAT); + val = smbus_read8(mmio, SMBHSTSTAT); val &= SMBHST_STAT_VAL_BITS; /* mask off reserved bits */ if (val & SMBHST_STAT_ERROR_BITS) return -5; /* error */ if (val == SMBHST_STAT_NOERROR) { - outb(val, smbus_io_base + SMBHSTSTAT); /* clear sts */ + smbus_write8(mmio, SMBHSTSTAT, val); /* clear sts */ return 0; } } while (--loops); return -3; /* timeout */ } -int do_smbus_recv_byte(u16 smbus_io_base, u8 device) +int do_smbus_recv_byte(u32 mmio, u8 device) { u8 byte; - if (smbus_wait_until_ready(smbus_io_base) < 0) + if (smbus_wait_until_ready(mmio) < 0) return -2; /* not ready */ /* set the device I'm talking to */ - outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR); + smbus_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 1); - byte = inb(smbus_io_base + SMBHSTCTRL); + byte = smbus_read8(mmio, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BTE_RW; /* set mode, start */ - outb(byte, smbus_io_base + SMBHSTCTRL); + smbus_write8(mmio, SMBHSTCTRL, byte); /* poll for transaction completion */ - if (smbus_wait_until_done(smbus_io_base) < 0) + if (smbus_wait_until_done(mmio) < 0) return -3; /* timeout or error */ /* read results of transaction */ - byte = inb(smbus_io_base + SMBHSTDAT0); + byte = smbus_read8(mmio, SMBHSTDAT0); return byte; } -int do_smbus_send_byte(u16 smbus_io_base, u8 device, u8 val) +int do_smbus_send_byte(u32 mmio, u8 device, u8 val) { u8 byte; - if (smbus_wait_until_ready(smbus_io_base) < 0) + if (smbus_wait_until_ready(mmio) < 0) return -2; /* not ready */ /* set the command... */ - outb(val, smbus_io_base + SMBHSTDAT0); + smbus_write8(mmio, SMBHSTDAT0, val); /* set the device I'm talking to */ - outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR); + smbus_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 0); - byte = inb(smbus_io_base + SMBHSTCTRL); + byte = smbus_read8(mmio, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BTE_RW; /* set mode, start */ - outb(byte, smbus_io_base + SMBHSTCTRL); + smbus_write8(mmio, SMBHSTCTRL, byte); /* poll for transaction completion */ - if (smbus_wait_until_done(smbus_io_base) < 0) + if (smbus_wait_until_done(mmio) < 0) return -3; /* timeout or error */ return 0; } -int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address) +int do_smbus_read_byte(u32 mmio, u8 device, u8 address) { u8 byte; - if (smbus_wait_until_ready(smbus_io_base) < 0) + if (smbus_wait_until_ready(mmio) < 0) return -2; /* not ready */ /* set the command/address... */ - outb(address & 0xff, smbus_io_base + SMBHSTCMD); + smbus_write8(mmio, SMBHSTCMD, address & 0xff); /* set the device I'm talking to */ - outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR); + smbus_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 1); - byte = inb(smbus_io_base + SMBHSTCTRL); + byte = smbus_read8(mmio, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BDT_RW; /* set mode, start */ - outb(byte, smbus_io_base + SMBHSTCTRL); + smbus_write8(mmio, SMBHSTCTRL, byte); /* poll for transaction completion */ - if (smbus_wait_until_done(smbus_io_base) < 0) + if (smbus_wait_until_done(mmio) < 0) return -3; /* timeout or error */ /* read results of transaction */ - byte = inb(smbus_io_base + SMBHSTDAT0); + byte = smbus_read8(mmio, SMBHSTDAT0); return byte; } -int do_smbus_write_byte(u16 smbus_io_base, u8 device, u8 address, u8 val) +int do_smbus_write_byte(u32 mmio, u8 device, u8 address, u8 val) { u8 byte; - if (smbus_wait_until_ready(smbus_io_base) < 0) + if (smbus_wait_until_ready(mmio) < 0) return -2; /* not ready */ /* set the command/address... */ - outb(address & 0xff, smbus_io_base + SMBHSTCMD); + smbus_write8(mmio, SMBHSTCMD, address & 0xff); /* set the device I'm talking to */ - outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR); + smbus_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 0); /* output value */ - outb(val, smbus_io_base + SMBHSTDAT0); + smbus_write8(mmio, SMBHSTDAT0, val); - byte = inb(smbus_io_base + SMBHSTCTRL); + byte = smbus_read8(mmio, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BDT_RW; /* set mode, start */ - outb(byte, smbus_io_base + SMBHSTCTRL); + smbus_write8(mmio, SMBHSTCTRL, byte); /* poll for transaction completion */ - if (smbus_wait_until_done(smbus_io_base) < 0) + if (smbus_wait_until_done(mmio) < 0) return -3; /* timeout or error */ return 0; diff --git a/src/soc/amd/stoneyridge/smbus_spd.c b/src/soc/amd/stoneyridge/smbus_spd.c index 384bc8a391..63b457c2c8 100644 --- a/src/soc/amd/stoneyridge/smbus_spd.c +++ b/src/soc/amd/stoneyridge/smbus_spd.c @@ -27,8 +27,7 @@ * sending offset for every byte. * Reads 128 bytes in 7-8 ms at 400 KHz. */ -static int readspd(uint16_t iobase, uint8_t SmbusSlaveAddress, - char *buffer, size_t count) +static int readspd(uint8_t SmbusSlaveAddress, char *buffer, size_t count) { uint8_t dev_addr; size_t index; @@ -36,8 +35,8 @@ static int readspd(uint16_t iobase, uint8_t SmbusSlaveAddress, char *pbuf = buffer; printk(BIOS_SPEW, "-------------READING SPD-----------\n"); - printk(BIOS_SPEW, "iobase: 0x%08X, SmbusSlave: 0x%08X, count: %d\n", - iobase, SmbusSlaveAddress, (int)count); + printk(BIOS_SPEW, "SmbusSlave: 0x%08X, count: %zd\n", + SmbusSlaveAddress, count); /* * Convert received device address to the format accepted by @@ -46,7 +45,7 @@ static int readspd(uint16_t iobase, uint8_t SmbusSlaveAddress, dev_addr = (SmbusSlaveAddress >> 1); /* Read the first SPD byte */ - error = do_smbus_read_byte(iobase, dev_addr, 0); + error = do_smbus_read_byte(SMBUS_MMIO_BASE, dev_addr, 0); if (error < 0) { printk(BIOS_ERR, "-------------SPD READ ERROR-----------\n"); return error; @@ -56,7 +55,7 @@ static int readspd(uint16_t iobase, uint8_t SmbusSlaveAddress, /* Read the remaining SPD bytes using do_smbus_recv_byte for speed */ for (index = 1 ; index < count ; index++) { - error = do_smbus_recv_byte(iobase, dev_addr); + error = do_smbus_recv_byte(SMBUS_MMIO_BASE, dev_addr); if (error < 0) { printk(BIOS_ERR, "-------------SPD READ ERROR-----------\n"); return error; @@ -70,24 +69,7 @@ static int readspd(uint16_t iobase, uint8_t SmbusSlaveAddress, return 0; } -static void write_pm_reg(int reg, int data) -{ - outb(reg, PM_INDEX); - outb(data, PM_DATA); -} - -static void setup_fch(uint16_t ioBase) -{ - write_pm_reg(SMB_ASF_IO_BASE, ioBase >> 8); - outb(SMB_SPEED_400KHZ, ioBase + SMBTIMING); - /* Clear all SMBUS status bits */ - outb(SMBHST_STAT_CLEAR, ioBase + SMBHSTSTAT); - outb(SMBSLV_STAT_CLEAR, ioBase + SMBSLVSTAT); -} - int sb_read_spd(uint8_t spdAddress, char *buf, size_t len) { - uint16_t ioBase = SMB_BASE_ADDR; - setup_fch(ioBase); - return readspd(ioBase, spdAddress, buf, len); + return readspd(spdAddress, buf, len); } diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index eb4188219b..c8d66ac3f2 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -28,6 +28,7 @@ #include <amdblocks/agesawrapper.h> #include <amdblocks/reset.h> #include <soc/southbridge.h> +#include <soc/smbus.h> #include <soc/smi.h> #include <soc/amd_pci_int_defs.h> #include <delay.h> @@ -619,6 +620,17 @@ static void setup_misc(int *reboot) } } +static void fch_smbus_init(void) +{ + pm_write8(SMB_ASF_IO_BASE, SMB_BASE_ADDR >> 8); + smbus_write8(SMBUS_MMIO_BASE, SMBTIMING, SMB_SPEED_400KHZ); + /* Clear all SMBUS status bits */ + smbus_write8(SMBUS_MMIO_BASE, SMBHSTSTAT, SMBHST_STAT_CLEAR); + smbus_write8(SMBUS_MMIO_BASE, SMBSLVSTAT, SMBSLV_STAT_CLEAR); + smbus_write8(ASF_MMIO_BASE, SMBHSTSTAT, SMBHST_STAT_CLEAR); + smbus_write8(ASF_MMIO_BASE, SMBSLVSTAT, SMBSLV_STAT_CLEAR); +} + /* Before console init */ void bootblock_fch_early_init(void) { @@ -631,6 +643,7 @@ void bootblock_fch_early_init(void) sb_spibase(); sb_disable_4dw_burst(); /* Must be disabled on CZ(ST) */ sb_acpi_mmio_decode(); + fch_smbus_init(); sb_enable_cf9_io(); setup_spread_spectrum(&reboot); setup_misc(&reboot); |