1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <arch/io.h>
4 #include <console/console.h>
5 #include <device/smbus_def.h>
6 #include <device/smbus_host.h>
7 #include <types.h>
8
9 #if CONFIG(DEBUG_SMBUS)
10 #define dprintk(args...) printk(BIOS_DEBUG, ##args)
11 #else
12 #define dprintk(args...) do {} while (0)
13 #endif
14
15 /* SMBus register offsets. */
16 #define SMBHSTSTAT 0x0
17 #define SMBHSTCTL 0x2
18 #define SMBHSTCMD 0x3
19 #define SMBXMITADD 0x4
20 #define SMBHSTDAT0 0x5
21 #define SMBHSTDAT1 0x6
22 #define SMBBLKDAT 0x7
23 #define SMBTRNSADD 0x9
24 #define SMBSLVDATA 0xa
25 #define SMLINK_PIN_CTL 0xe
26 #define SMBUS_PIN_CTL 0xf
27 #define SMBSLVCMD 0x11
28
29 #define SMB_RCV_SLVA SMBTRNSADD
30
31 /* I801 command constants */
32 #define I801_QUICK (0 << 2)
33 #define I801_BYTE (1 << 2)
34 #define I801_BYTE_DATA (2 << 2)
35 #define I801_WORD_DATA (3 << 2)
36 #define I801_PROCESS_CALL (4 << 2)
37 #define I801_BLOCK_DATA (5 << 2)
38 #define I801_I2C_BLOCK_DATA (6 << 2) /* ICH5 and later */
39
40 /* I801 Host Control register bits */
41 #define SMBHSTCNT_INTREN (1 << 0)
42 #define SMBHSTCNT_KILL (1 << 1)
43 #define SMBHSTCNT_LAST_BYTE (1 << 5)
44 #define SMBHSTCNT_START (1 << 6)
45 #define SMBHSTCNT_PEC_EN (1 << 7) /* ICH3 and later */
46
47 /* I801 Hosts Status register bits */
48 #define SMBHSTSTS_BYTE_DONE (1 << 7)
49 #define SMBHSTSTS_INUSE_STS (1 << 6)
50 #define SMBHSTSTS_SMBALERT_STS (1 << 5)
51 #define SMBHSTSTS_FAILED (1 << 4)
52 #define SMBHSTSTS_BUS_ERR (1 << 3)
53 #define SMBHSTSTS_DEV_ERR (1 << 2)
54 #define SMBHSTSTS_INTR (1 << 1)
55 #define SMBHSTSTS_HOST_BUSY (1 << 0)
56
57 /* For SMBXMITADD register. */
58 #define XMIT_WRITE(dev) (((dev) << 1) | 0)
59 #define XMIT_READ(dev) (((dev) << 1) | 1)
60
61 #define SMBUS_TIMEOUT (10 * 1000 * 100)
62 #define SMBUS_BLOCK_MAXLEN 32
63
64 /* block_cmd_loop flags */
65 #define BLOCK_READ 0
66 #define BLOCK_WRITE (1 << 0)
67 #define BLOCK_I2C (1 << 1)
68
smbus_delay(void)69 static void smbus_delay(void)
70 {
71 inb(0x80);
72 }
73
host_outb(uintptr_t base,u8 reg,u8 value)74 static void host_outb(uintptr_t base, u8 reg, u8 value)
75 {
76 outb(value, base + reg);
77 }
78
host_inb(uintptr_t base,u8 reg)79 static u8 host_inb(uintptr_t base, u8 reg)
80 {
81 return inb(base + reg);
82 }
83
host_and_or(uintptr_t base,u8 reg,u8 mask,u8 or)84 static void host_and_or(uintptr_t base, u8 reg, u8 mask, u8 or)
85 {
86 u8 value;
87 value = host_inb(base, reg);
88 value &= mask;
89 value |= or;
90 host_outb(base, reg, value);
91 }
92
smbus_host_reset(uintptr_t base)93 void smbus_host_reset(uintptr_t base)
94 {
95 /* Disable interrupt generation. */
96 host_outb(base, SMBHSTCTL, 0);
97
98 /* Clear any lingering errors, so transactions can run. */
99 host_and_or(base, SMBHSTSTAT, 0xff, 0);
100 }
101
smbus_set_slave_addr(uintptr_t base,u8 slave_address)102 void smbus_set_slave_addr(uintptr_t base, u8 slave_address)
103 {
104 host_outb(base, SMB_RCV_SLVA, slave_address);
105 }
106
host_completed(u8 status)107 static int host_completed(u8 status)
108 {
109 if (status & SMBHSTSTS_HOST_BUSY)
110 return 0;
111
112 /* These status bits do not imply completion of transaction. */
113 status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS |
114 SMBHSTSTS_SMBALERT_STS);
115 return status != 0;
116 }
117
recover_master(uintptr_t base,int ret)118 static int recover_master(uintptr_t base, int ret)
119 {
120 /* TODO: Depending of the failure, drive KILL transaction
121 * or force soft reset on SMBus master controller.
122 */
123 printk(BIOS_ERR, "SMBus: Fatal master timeout (%d)\n", ret);
124 return ret;
125 }
126
cb_err_from_stat(u8 status)127 static int cb_err_from_stat(u8 status)
128 {
129 /* These status bits do not imply errors. */
130 status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS |
131 SMBHSTSTS_SMBALERT_STS);
132
133 if (status == SMBHSTSTS_INTR)
134 return 0;
135
136 return SMBUS_ERROR;
137 }
138
setup_command(uintptr_t base,u8 ctrl,u8 xmitadd)139 static int setup_command(uintptr_t base, u8 ctrl, u8 xmitadd)
140 {
141 unsigned int loops = SMBUS_TIMEOUT;
142 u8 host_busy;
143
144 do {
145 smbus_delay();
146 host_busy = host_inb(base, SMBHSTSTAT) & SMBHSTSTS_HOST_BUSY;
147 } while (--loops && host_busy);
148
149 if (loops == 0)
150 return recover_master(base, SMBUS_WAIT_UNTIL_READY_TIMEOUT);
151
152 /* Clear any lingering errors, so the transaction will run. */
153 host_and_or(base, SMBHSTSTAT, 0xff, 0);
154
155 /* Set up transaction */
156 /* Disable interrupts */
157 host_outb(base, SMBHSTCTL, ctrl);
158
159 /* Set the device I'm talking to. */
160 host_outb(base, SMBXMITADD, xmitadd);
161
162 return 0;
163 }
164
execute_command(uintptr_t base)165 static int execute_command(uintptr_t base)
166 {
167 unsigned int loops = SMBUS_TIMEOUT;
168 u8 status;
169
170 /* Start the command. */
171 host_and_or(base, SMBHSTCTL, 0xff, SMBHSTCNT_START);
172
173 /* Poll for it to start. */
174 do {
175 smbus_delay();
176
177 /* If we poll too slow, we could miss HOST_BUSY flag
178 * set and detect INTR or x_ERR flags instead here.
179 */
180 status = host_inb(base, SMBHSTSTAT);
181 status &= ~(SMBHSTSTS_SMBALERT_STS | SMBHSTSTS_INUSE_STS);
182 } while (--loops && status == 0);
183
184 if (loops == 0)
185 return recover_master(base,
186 SMBUS_WAIT_UNTIL_ACTIVE_TIMEOUT);
187
188 return 0;
189 }
190
complete_command(uintptr_t base)191 static int complete_command(uintptr_t base)
192 {
193 unsigned int loops = SMBUS_TIMEOUT;
194 u8 status;
195
196 do {
197 smbus_delay();
198 status = host_inb(base, SMBHSTSTAT);
199 } while (--loops && !host_completed(status));
200
201 if (loops == 0)
202 return recover_master(base,
203 SMBUS_WAIT_UNTIL_DONE_TIMEOUT);
204
205 return cb_err_from_stat(status);
206 }
207
smbus_read_cmd(uintptr_t base,u8 ctrl,u8 device,u8 address)208 static int smbus_read_cmd(uintptr_t base, u8 ctrl, u8 device, u8 address)
209 {
210 int ret;
211 u16 word;
212
213 /* Set up for a byte data read. */
214 ret = setup_command(base, ctrl, XMIT_READ(device));
215 if (ret < 0)
216 return ret;
217
218 /* Set the command/address... */
219 host_outb(base, SMBHSTCMD, address);
220
221 /* Clear the data bytes... */
222 host_outb(base, SMBHSTDAT0, 0);
223 host_outb(base, SMBHSTDAT1, 0);
224
225 /* Start the command */
226 ret = execute_command(base);
227 if (ret < 0)
228 return ret;
229
230 /* Poll for transaction completion */
231 ret = complete_command(base);
232 if (ret < 0)
233 return ret;
234
235 /* Read results of transaction */
236 word = host_inb(base, SMBHSTDAT0);
237 if (ctrl == I801_WORD_DATA)
238 word |= host_inb(base, SMBHSTDAT1) << 8;
239
240 return word;
241 }
242
smbus_write_cmd(uintptr_t base,u8 ctrl,u8 device,u8 address,u16 data)243 static int smbus_write_cmd(uintptr_t base, u8 ctrl, u8 device, u8 address, u16 data)
244 {
245 int ret;
246
247 /* Set up for a byte data write. */
248 ret = setup_command(base, ctrl, XMIT_WRITE(device));
249 if (ret < 0)
250 return ret;
251
252 /* Set the command/address... */
253 host_outb(base, SMBHSTCMD, address);
254
255 /* Set the data bytes... */
256 if (ctrl >= I801_BYTE_DATA)
257 host_outb(base, SMBHSTDAT0, data & 0xff);
258 if (ctrl == I801_WORD_DATA)
259 host_outb(base, SMBHSTDAT1, data >> 8);
260
261 /* Start the command */
262 ret = execute_command(base);
263 if (ret < 0)
264 return ret;
265
266 /* Poll for transaction completion */
267 return complete_command(base);
268 }
269
block_cmd_loop(uintptr_t base,u8 * buf,size_t max_bytes,int flags)270 static int block_cmd_loop(uintptr_t base, u8 *buf, size_t max_bytes, int flags)
271 {
272 u8 status;
273 unsigned int loops = SMBUS_TIMEOUT;
274 int ret;
275 size_t bytes = 0;
276 int is_write_cmd = flags & BLOCK_WRITE;
277 int sw_drives_nak = flags & BLOCK_I2C;
278
279 /* Hardware limitations. */
280 if (flags == (BLOCK_WRITE | BLOCK_I2C))
281 return SMBUS_ERROR;
282
283 /* Set number of bytes to transfer. */
284 /* Reset number of bytes to transfer so we notice later it
285 * was really updated with the transaction. */
286 if (!sw_drives_nak) {
287 if (is_write_cmd)
288 host_outb(base, SMBHSTDAT0, max_bytes);
289 else
290 host_outb(base, SMBHSTDAT0, 0);
291 }
292
293 /* Send first byte from buffer, bytes_sent increments after
294 * hardware acknowledges it.
295 */
296 if (is_write_cmd)
297 host_outb(base, SMBBLKDAT, *buf++);
298
299 /* Start the command */
300 ret = execute_command(base);
301 if (ret < 0)
302 return ret;
303
304 /* Poll for transaction completion */
305 do {
306 status = host_inb(base, SMBHSTSTAT);
307
308 if (status & SMBHSTSTS_BYTE_DONE) { /* Byte done */
309
310 if (is_write_cmd) {
311 bytes++;
312 if (bytes < max_bytes)
313 host_outb(base, SMBBLKDAT, *buf++);
314 } else {
315 if (bytes < max_bytes)
316 *buf++ = host_inb(base, SMBBLKDAT);
317 bytes++;
318
319 /* Indicate that next byte is the last one. */
320 if (sw_drives_nak && (bytes + 1 >= max_bytes)) {
321 host_and_or(base, SMBHSTCTL, 0xff,
322 SMBHSTCNT_LAST_BYTE);
323 }
324 }
325
326 /* Engine internally completes the transaction
327 * and clears HOST_BUSY flag once the byte count
328 * has been reached or LAST_BYTE was set.
329 */
330 host_outb(base, SMBHSTSTAT, SMBHSTSTS_BYTE_DONE);
331 }
332
333 } while (--loops && !host_completed(status));
334
335 dprintk("%s: status = %02x, len = %zd / %zd, loops = %d\n",
336 __func__, status, bytes, max_bytes, SMBUS_TIMEOUT - loops);
337
338 if (loops == 0)
339 return recover_master(base, SMBUS_WAIT_UNTIL_DONE_TIMEOUT);
340
341 ret = cb_err_from_stat(status);
342 if (ret < 0)
343 return ret;
344
345 return bytes;
346 }
347
do_smbus_read_byte(uintptr_t base,u8 device,u8 address)348 int do_smbus_read_byte(uintptr_t base, u8 device, u8 address)
349 {
350 return smbus_read_cmd(base, I801_BYTE_DATA, device, address);
351 }
352
do_smbus_read_word(uintptr_t base,u8 device,u8 address)353 int do_smbus_read_word(uintptr_t base, u8 device, u8 address)
354 {
355 return smbus_read_cmd(base, I801_WORD_DATA, device, address);
356 }
357
do_smbus_send_byte(uintptr_t base,u8 device,u8 data)358 int do_smbus_send_byte(uintptr_t base, u8 device, u8 data)
359 {
360 return smbus_write_cmd(base, I801_BYTE, device, data, 0x00);
361 }
362
do_smbus_write_byte(uintptr_t base,u8 device,u8 address,u8 data)363 int do_smbus_write_byte(uintptr_t base, u8 device, u8 address, u8 data)
364 {
365 return smbus_write_cmd(base, I801_BYTE_DATA, device, address, data);
366 }
367
do_smbus_write_word(uintptr_t base,u8 device,u8 address,u16 data)368 int do_smbus_write_word(uintptr_t base, u8 device, u8 address, u16 data)
369 {
370 return smbus_write_cmd(base, I801_WORD_DATA, device, address, data);
371 }
372
do_smbus_block_read(uintptr_t base,u8 device,u8 cmd,size_t max_bytes,u8 * buf)373 int do_smbus_block_read(uintptr_t base, u8 device, u8 cmd, size_t max_bytes, u8 *buf)
374 {
375 int ret, slave_bytes;
376
377 max_bytes = MIN(SMBUS_BLOCK_MAXLEN, max_bytes);
378
379 /* Set up for a block data read. */
380 ret = setup_command(base, I801_BLOCK_DATA, XMIT_READ(device));
381 if (ret < 0)
382 return ret;
383
384 /* Set the command/address... */
385 host_outb(base, SMBHSTCMD, cmd);
386
387 /* Execute block transaction. */
388 ret = block_cmd_loop(base, buf, max_bytes, BLOCK_READ);
389 if (ret < 0)
390 return ret;
391
392 /* Post-check we received complete message. */
393 slave_bytes = host_inb(base, SMBHSTDAT0);
394 if (ret < slave_bytes)
395 return SMBUS_ERROR;
396
397 return ret;
398 }
399
400 /*
401 * The caller is responsible of settings HOSTC I2C_EN bit prior to making this
402 * call!
403 */
do_smbus_process_call(uintptr_t base,u8 device,u8 cmd,u16 data,u16 * buf)404 int do_smbus_process_call(uintptr_t base, u8 device, u8 cmd, u16 data, u16 *buf)
405 {
406 int ret;
407
408 /* Set up for process call */
409 ret = setup_command(base, I801_PROCESS_CALL, XMIT_WRITE(device));
410 if (ret < 0)
411 return ret;
412
413 /* cmd will only be send if I2C_EN is zero */
414 host_outb(base, SMBHSTCMD, cmd);
415
416 host_outb(base, SMBHSTDAT0, data & 0x00ff);
417 host_outb(base, SMBHSTDAT1, (data & 0xff00) >> 8);
418
419 /* Start the command */
420 ret = execute_command(base);
421 if (ret < 0)
422 return ret;
423
424 /* Poll for transaction completion */
425 ret = complete_command(base);
426 if (ret < 0)
427 return ret;
428
429 /* Read results of transaction */
430 *buf = host_inb(base, SMBHSTDAT0);
431 *buf |= (host_inb(base, SMBHSTDAT1) << 8);
432
433 return ret;
434 }
435
do_smbus_block_write(uintptr_t base,u8 device,u8 cmd,const size_t bytes,const u8 * buf)436 int do_smbus_block_write(uintptr_t base, u8 device, u8 cmd, const size_t bytes, const u8 *buf)
437 {
438 int ret;
439
440 if (bytes > SMBUS_BLOCK_MAXLEN)
441 return SMBUS_ERROR;
442
443 /* Set up for a block data write. */
444 ret = setup_command(base, I801_BLOCK_DATA, XMIT_WRITE(device));
445 if (ret < 0)
446 return ret;
447
448 /* Set the command/address... */
449 host_outb(base, SMBHSTCMD, cmd);
450
451 /* Execute block transaction. */
452 ret = block_cmd_loop(base, (u8 *)buf, bytes, BLOCK_WRITE);
453 if (ret < 0)
454 return ret;
455
456 if (ret < bytes)
457 return SMBUS_ERROR;
458
459 return ret;
460 }
461
462 /* Only since ICH5 */
has_i2c_read_command(void)463 static int has_i2c_read_command(void)
464 {
465 if (CONFIG(SOUTHBRIDGE_INTEL_I82371EB) ||
466 CONFIG(SOUTHBRIDGE_INTEL_I82801DX))
467 return 0;
468 return 1;
469 }
470
do_i2c_eeprom_read(uintptr_t base,u8 device,u8 offset,const size_t bytes,u8 * buf)471 int do_i2c_eeprom_read(uintptr_t base, u8 device, u8 offset, const size_t bytes, u8 *buf)
472 {
473 int ret;
474
475 if (!has_i2c_read_command())
476 return SMBUS_ERROR;
477
478 /* Set up for a i2c block data read.
479 *
480 * FIXME: Address parameter changes to XMIT_READ(device) with
481 * some revision of PCH. Presumably hardware revisions that
482 * do not have i2c block write support internally set LSB.
483 */
484 ret = setup_command(base, I801_I2C_BLOCK_DATA,
485 XMIT_WRITE(device));
486 if (ret < 0)
487 return ret;
488
489 /* device offset */
490 host_outb(base, SMBHSTDAT1, offset);
491
492 /* Execute block transaction. */
493 ret = block_cmd_loop(base, buf, bytes, BLOCK_READ | BLOCK_I2C);
494 if (ret < 0)
495 return ret;
496
497 /* Post-check we received complete message. */
498 if (ret < bytes)
499 return SMBUS_ERROR;
500
501 return ret;
502 }
503
504 /*
505 * The caller is responsible of settings HOSTC I2C_EN bit prior to making this
506 * call!
507 */
do_i2c_block_write(uintptr_t base,u8 device,size_t bytes,u8 * buf)508 int do_i2c_block_write(uintptr_t base, u8 device, size_t bytes, u8 *buf)
509 {
510 u8 cmd;
511 int ret;
512
513 if (!CONFIG(SOC_INTEL_BRASWELL))
514 return SMBUS_ERROR;
515
516 if (!bytes || (bytes > SMBUS_BLOCK_MAXLEN))
517 return SMBUS_ERROR;
518
519 /* Set up for a block data write. */
520 ret = setup_command(base, I801_BLOCK_DATA, XMIT_WRITE(device));
521 if (ret < 0)
522 return ret;
523
524 /*
525 * In i2c mode SMBus controller sequence on bus will be:
526 * <SMBXINTADD> <SMBHSTDAT1> <SMBBLKDAT> .. <SMBBLKDAT>
527 * The SMBHSTCMD must be written also to ensure the SMBUs controller
528 * will generate the i2c sequence.
529 */
530 cmd = *buf++;
531 bytes--;
532 host_outb(base, SMBHSTCMD, cmd);
533 host_outb(base, SMBHSTDAT1, cmd);
534
535 /* Execute block transaction. */
536 ret = block_cmd_loop(base, buf, bytes, BLOCK_WRITE);
537 if (ret < 0)
538 return ret;
539
540 if (ret < bytes)
541 return SMBUS_ERROR;
542
543 ret++; /* 1st byte has been written using SMBHSTDAT1 */
544 return ret;
545 }
546