1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
5 #include <device/mmio.h>
6 #include <device/smbus_host.h>
7 #include <amdblocks/acpimmio.h>
8 #include <amdblocks/smbus.h>
9 #include <soc/southbridge.h>
12 * Between 1-10 seconds, We should never timeout normally
13 * Longer than this is just painful when a timeout condition occurs.
15 #define SMBUS_TIMEOUT (100 * 1000 * 10)
17 /* FIXME: Passing host base for SMBUS is not long-term solution.
18 It is possible to have multiple buses behind same host. */
20 static u8
controller_read8(const uintptr_t base
, const u8 reg
)
22 return read8p(base
+ reg
);
25 static void controller_write8(const uintptr_t base
, const u8 reg
, const u8 val
)
27 write8p(base
+ reg
, val
);
30 static int smbus_wait_until_ready(uintptr_t mmio
)
32 if ((mmio
!= (uintptr_t)acpimmio_smbus
) &&
33 (mmio
!= (uintptr_t)acpimmio_asf
)) {
34 printk(BIOS_ERR
, "Invalid SMBus or ASF base %#" PRIxPTR
"\n", mmio
);
39 loops
= SMBUS_TIMEOUT
;
42 val
= controller_read8(mmio
, SMBHSTSTAT
);
43 val
&= SMBHST_STAT_VAL_BITS
;
44 if (val
== 0) { /* ready now */
47 controller_write8(mmio
, SMBHSTSTAT
, val
);
49 return -2; /* time out */
52 static int smbus_wait_until_done(uintptr_t mmio
)
55 loops
= SMBUS_TIMEOUT
;
59 val
= controller_read8(mmio
, SMBHSTSTAT
);
60 val
&= SMBHST_STAT_VAL_BITS
; /* mask off reserved bits */
61 if (val
& SMBHST_STAT_ERROR_BITS
)
62 return -5; /* error */
63 /* check IRQ status bit to see if the last host command is completed */
64 if (val
== SMBHST_STAT_INTERRUPT
) {
65 controller_write8(mmio
, SMBHSTSTAT
, val
); /* clr sts */
69 return -3; /* timeout */
72 int do_smbus_recv_byte(uintptr_t mmio
, u8 device
)
76 if (smbus_wait_until_ready(mmio
) < 0)
77 return -2; /* not ready */
79 /* set the device I'm talking to */
80 controller_write8(mmio
, SMBHSTADDR
, ((device
& 0x7f) << 1) | 1);
82 byte
= controller_read8(mmio
, SMBHSTCTRL
);
83 byte
&= ~SMBHST_CTRL_MODE_BITS
; /* Clear [4:2] */
84 byte
|= SMBHST_CTRL_STRT
| SMBHST_CTRL_BTE_RW
; /* set mode, start */
85 controller_write8(mmio
, SMBHSTCTRL
, byte
);
87 /* poll for transaction completion */
88 if (smbus_wait_until_done(mmio
) < 0)
89 return -3; /* timeout or error */
91 /* read results of transaction */
92 byte
= controller_read8(mmio
, SMBHSTDAT0
);
97 int do_smbus_send_byte(uintptr_t mmio
, u8 device
, u8 val
)
101 if (smbus_wait_until_ready(mmio
) < 0)
102 return -2; /* not ready */
104 /* set the command... */
105 controller_write8(mmio
, SMBHSTDAT0
, val
);
107 /* set the device I'm talking to */
108 controller_write8(mmio
, SMBHSTADDR
, ((device
& 0x7f) << 1) | 0);
110 byte
= controller_read8(mmio
, SMBHSTCTRL
);
111 byte
&= ~SMBHST_CTRL_MODE_BITS
; /* Clear [4:2] */
112 byte
|= SMBHST_CTRL_STRT
| SMBHST_CTRL_BTE_RW
; /* set mode, start */
113 controller_write8(mmio
, SMBHSTCTRL
, byte
);
115 /* poll for transaction completion */
116 if (smbus_wait_until_done(mmio
) < 0)
117 return -3; /* timeout or error */
122 int do_smbus_read_byte(uintptr_t mmio
, u8 device
, u8 address
)
126 if (smbus_wait_until_ready(mmio
) < 0)
127 return -2; /* not ready */
129 /* set the command/address... */
130 controller_write8(mmio
, SMBHSTCMD
, address
& 0xff);
132 /* set the device I'm talking to */
133 controller_write8(mmio
, SMBHSTADDR
, ((device
& 0x7f) << 1) | 1);
135 byte
= controller_read8(mmio
, SMBHSTCTRL
);
136 byte
&= ~SMBHST_CTRL_MODE_BITS
; /* Clear [4:2] */
137 byte
|= SMBHST_CTRL_STRT
| SMBHST_CTRL_BDT_RW
; /* set mode, start */
138 controller_write8(mmio
, SMBHSTCTRL
, byte
);
140 /* poll for transaction completion */
141 if (smbus_wait_until_done(mmio
) < 0)
142 return -3; /* timeout or error */
144 /* read results of transaction */
145 byte
= controller_read8(mmio
, SMBHSTDAT0
);
150 int do_smbus_write_byte(uintptr_t mmio
, u8 device
, u8 address
, u8 val
)
154 if (smbus_wait_until_ready(mmio
) < 0)
155 return -2; /* not ready */
157 /* set the command/address... */
158 controller_write8(mmio
, SMBHSTCMD
, address
& 0xff);
160 /* set the device I'm talking to */
161 controller_write8(mmio
, SMBHSTADDR
, ((device
& 0x7f) << 1) | 0);
164 controller_write8(mmio
, SMBHSTDAT0
, val
);
166 byte
= controller_read8(mmio
, SMBHSTCTRL
);
167 byte
&= ~SMBHST_CTRL_MODE_BITS
; /* Clear [4:2] */
168 byte
|= SMBHST_CTRL_STRT
| SMBHST_CTRL_BDT_RW
; /* set mode, start */
169 controller_write8(mmio
, SMBHSTCTRL
, byte
);
171 /* poll for transaction completion */
172 if (smbus_wait_until_done(mmio
) < 0)
173 return -3; /* timeout or error */