2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Authors: Joe Kloss; Ravi Pokala (rpokala@freebsd.org)
6 * Copyright (c) 2017-2018 Panasas
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 /* A detailed description of this device is present in imcsmb_pci.c */
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/module.h>
38 #include <sys/endian.h>
39 #include <sys/errno.h>
41 #include <sys/mutex.h>
42 #include <sys/syslog.h>
45 #include <machine/bus.h>
46 #include <machine/atomic.h>
48 #include <dev/pci/pcivar.h>
49 #include <dev/pci/pcireg.h>
51 #include <dev/smbus/smbconf.h>
53 #include "imcsmb_reg.h"
54 #include "imcsmb_var.h"
57 static int imcsmb_attach(device_t dev);
58 static int imcsmb_detach(device_t dev);
59 static int imcsmb_probe(device_t dev);
62 static int imcsmb_callback(device_t dev, int index, void *data);
63 static int imcsmb_readb(device_t dev, u_char slave, char cmd, char *byte);
64 static int imcsmb_readw(device_t dev, u_char slave, char cmd, short *word);
65 static int imcsmb_writeb(device_t dev, u_char slave, char cmd, char byte);
66 static int imcsmb_writew(device_t dev, u_char slave, char cmd, short word);
68 /* All the read/write methods wrap around this. */
69 static int imcsmb_transfer(device_t dev, u_char slave, char cmd, void *data,
70 int word_op, int write_op);
73 * device_attach() method. Set up the softc, including getting the set of the
74 * parent imcsmb_pci's registers that we will use. Create the smbus(4) device,
75 * which any SMBus slave device drivers will connect to.
80 * Device being attached.
83 imcsmb_attach(device_t dev)
85 struct imcsmb_softc *sc;
88 /* Initialize private state */
89 sc = device_get_softc(dev);
91 sc->imcsmb_pci = device_get_parent(dev);
92 sc->regs = device_get_ivars(dev);
94 /* Create the smbus child */
95 sc->smbus = device_add_child(dev, "smbus", -1);
96 if (sc->smbus == NULL) {
97 /* Nothing has been allocated, so there's no cleanup. */
98 device_printf(dev, "Child smbus not added\n");
103 /* Attach the smbus child. */
104 if ((rc = bus_generic_attach(dev)) != 0) {
105 device_printf(dev, "Failed to attach smbus: %d\n", rc);
113 * device_detach() method. attach() didn't do any allocations, so all that's
114 * needed here is to free up any downstream drivers and children.
119 * Device being detached.
122 imcsmb_detach(device_t dev)
126 /* Detach any attached drivers */
127 rc = bus_generic_detach(dev);
129 /* Remove all children */
130 rc = device_delete_children(dev);
137 * device_probe() method. All the actual probing was done by the imcsmb_pci
138 * parent, so just report success.
143 * Device being probed.
146 imcsmb_probe(device_t dev)
149 device_set_desc(dev, "iMC SMBus controller");
150 return (BUS_PROBE_DEFAULT);
154 * smbus_callback() method. Call the parent imcsmb_pci's request or release
155 * function to quiesce / restart firmware tasks which might use the SMBus.
160 * Device being requested or released.
163 * Either SMB_REQUEST_BUS or SMB_RELEASE_BUS.
166 * Tell's the rest of the SMBus subsystem to allow or disallow waiting;
167 * this driver only works with SMB_DONTWAIT.
170 imcsmb_callback(device_t dev, int index, void *data)
172 struct imcsmb_softc *sc;
176 sc = device_get_softc(dev);
180 case SMB_REQUEST_BUS: {
181 if (*how != SMB_DONTWAIT) {
185 rc = imcsmb_pci_request_bus(sc->imcsmb_pci);
188 case SMB_RELEASE_BUS:
189 imcsmb_pci_release_bus(sc->imcsmb_pci);
202 * smbus_readb() method. Thin wrapper around imcsmb_transfer().
209 * The SMBus address of the target device.
212 * The SMBus command for the target device; this is the offset for SPDs,
213 * or the register number for TSODs.
216 * The byte which was read.
219 imcsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
222 return (imcsmb_transfer(dev, slave, cmd, byte, FALSE, FALSE));
226 * smbus_readw() method. Thin wrapper around imcsmb_transfer().
233 * The SMBus address of the target device.
236 * The SMBus command for the target device; this is the offset for SPDs,
237 * or the register number for TSODs.
240 * The word which was read.
243 imcsmb_readw(device_t dev, u_char slave, char cmd, short *word)
246 return (imcsmb_transfer(dev, slave, cmd, word, TRUE, FALSE));
250 * smbus_writeb() method. Thin wrapper around imcsmb_transfer().
257 * The SMBus address of the target device.
260 * The SMBus command for the target device; this is the offset for SPDs,
261 * or the register number for TSODs.
267 imcsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
270 return (imcsmb_transfer(dev, slave, cmd, &byte, FALSE, TRUE));
274 * smbus_writew() method. Thin wrapper around imcsmb_transfer().
281 * The SMBus address of the target device.
284 * The SMBus command for the target device; this is the offset for SPDs,
285 * or the register number for TSODs.
291 imcsmb_writew(device_t dev, u_char slave, char cmd, short word)
294 return (imcsmb_transfer(dev, slave, cmd, &word, TRUE, TRUE));
298 * Manipulate the PCI control registers to read data from or write data to the
301 * @author Joe Kloss, rpokala
306 * The SMBus address of the target device.
309 * The SMBus command for the target device; this is the offset for SPDs,
310 * or the register number for TSODs.
312 * @param[in,out] data
313 * Pointer to either the value to be written, or where to place the value
317 * Bool: is this a word operation?
319 * @param[in] write_op
320 * Bool: is this a write operation?
323 imcsmb_transfer(device_t dev, u_char slave, char cmd, void *data, int word_op,
326 struct imcsmb_softc *sc;
331 uint32_t orig_cntl_val;
338 sc = device_get_softc(dev);
344 /* We modify the value of the control register; save the original, so
345 * we can restore it later
347 orig_cntl_val = pci_read_config(sc->imcsmb_pci,
348 sc->regs->smb_cntl, 4);
349 cntl_val = orig_cntl_val;
352 * Set up the SMBCNTL register
355 /* [31:28] Clear the existing value of the DTI bits, then set them to
356 * the four high bits of the slave address.
358 cntl_val &= ~IMCSMB_CNTL_DTI_MASK;
359 cntl_val |= ((uint32_t) slave & 0xf0) << 24;
361 /* [27:27] Set the CLK_OVERRIDE bit, to enable normal operation */
362 cntl_val |= IMCSMB_CNTL_CLK_OVERRIDE;
364 /* [26:26] Clear the WRITE_DISABLE bit; the datasheet says this isn't
365 * necessary, but empirically, it is.
367 cntl_val &= ~IMCSMB_CNTL_WRITE_DISABLE_BIT;
369 /* [9:9] Clear the POLL_EN bit, to stop the hardware TSOD polling. */
370 cntl_val &= ~IMCSMB_CNTL_POLL_EN;
373 * Set up the SMBCMD register
376 /* [31:31] Set the TRIGGER bit; when this gets written, the controller
377 * will issue the command.
379 cmd_val = IMCSMB_CMD_TRIGGER_BIT;
381 /* [29:29] For word operations, set the WORD_ACCESS bit. */
383 cmd_val |= IMCSMB_CMD_WORD_ACCESS;
386 /* [27:27] For write operations, set the WRITE bit. */
388 cmd_val |= IMCSMB_CMD_WRITE_BIT;
391 /* [26:24] The three non-DTI, non-R/W bits of the slave address. */
392 cmd_val |= (uint32_t) ((slave & 0xe) << 23);
394 /* [23:16] The command (offset in the case of an EEPROM, or register in
395 * the case of TSOD or NVDIMM controller).
397 cmd_val |= (uint32_t) ((uint8_t) cmd << 16);
399 /* [15:0] The data to be written for a write operation. */
402 /* The datasheet says the controller uses different
403 * endianness for word operations on I2C vs SMBus!
404 * I2C: [15:8] = MSB; [7:0] = LSB
405 * SMB: [15:8] = LSB; [7:0] = MSB
406 * As a practical matter, this controller is very
407 * specifically for use with DIMMs, the SPD (and
408 * NVDIMM controllers) are only accessed as bytes,
409 * the temperature sensor is only accessed as words, and
410 * the temperature sensors are I2C. Thus, byte-swap the
413 lword = htobe16(lword);
415 /* For byte operations, the data goes in the LSB, and
416 * the MSB is a don't care.
418 lword = (uint16_t) (lbyte & 0xff);
423 /* Write the updated value to the control register first, to disable
424 * the hardware TSOD polling.
426 pci_write_config(sc->imcsmb_pci, sc->regs->smb_cntl, cntl_val, 4);
428 /* Poll on the BUSY bit in the status register until clear, or timeout.
429 * We just cleared the auto-poll bit, so we need to make sure the device
430 * is idle before issuing a command. We can safely timeout after 35 ms,
431 * as this is the maximum time the SMBus spec allows for a transaction.
433 for (i = 4; i != 0; i--) {
434 stat_val = pci_read_config(sc->imcsmb_pci, sc->regs->smb_stat,
436 if ((stat_val & IMCSMB_STATUS_BUSY_BIT) == 0) {
439 pause("imcsmb", 10 * hz / 1000);
443 device_printf(sc->dev,
444 "transfer: timeout waiting for device to settle\n");
447 /* Now that polling has stopped, we can write the command register. This
448 * starts the SMBus command.
450 pci_write_config(sc->imcsmb_pci, sc->regs->smb_cmd, cmd_val, 4);
452 /* Wait for WRITE_DATA_DONE/READ_DATA_VALID to be set, or timeout and
453 * fail. We wait up to 35ms.
455 for (i = 35000; i != 0; i -= 10)
458 stat_val = pci_read_config(sc->imcsmb_pci, sc->regs->smb_stat,
460 /* For a write, the bits holding the data contain the data being
461 * written. You'd think that would cause the READ_DATA_VALID bit
462 * to be cleared, because the data bits no longer contain valid
463 * data from the most recent read operation. While that would be
464 * logical, that's not the case here: READ_DATA_VALID is only
465 * cleared when starting a read operation, and WRITE_DATA_DONE
466 * is only cleared when starting a write operation.
469 if ((stat_val & IMCSMB_STATUS_WRITE_DATA_DONE) != 0) {
473 if ((stat_val & IMCSMB_STATUS_READ_DATA_VALID) != 0) {
480 device_printf(dev, "transfer timeout\n");
484 /* It is generally the case that this bit indicates non-ACK, but it
485 * could also indicate other bus errors. There's no way to tell the
488 if ((stat_val & IMCSMB_STATUS_BUS_ERROR_BIT) != 0) {
489 /* While it is not documented, empirically, SPD page-change
490 * commands (writes with DTI = 0x60) always complete with the
491 * error bit set. So, ignore it in those cases.
493 if ((slave & 0xf0) != 0x60) {
499 /* For a read operation, copy the data out */
502 /* The data is returned in bits [15:0]; as discussed
505 lword = (uint16_t) (stat_val & 0xffff);
506 lword = htobe16(lword);
509 /* The data is returned in bits [7:0] */
510 lbyte = (uint8_t) (stat_val & 0xff);
515 /* A lack of an error is, de facto, success. */
519 /* Restore the original value of the control register. */
520 pci_write_config(sc->imcsmb_pci, sc->regs->smb_cntl, orig_cntl_val, 4);
524 /* Our device class */
525 static devclass_t imcsmb_devclass;
528 static device_method_t imcsmb_methods[] = {
529 /* Device interface */
530 DEVMETHOD(device_attach, imcsmb_attach),
531 DEVMETHOD(device_detach, imcsmb_detach),
532 DEVMETHOD(device_probe, imcsmb_probe),
535 DEVMETHOD(smbus_callback, imcsmb_callback),
536 DEVMETHOD(smbus_readb, imcsmb_readb),
537 DEVMETHOD(smbus_readw, imcsmb_readw),
538 DEVMETHOD(smbus_writeb, imcsmb_writeb),
539 DEVMETHOD(smbus_writew, imcsmb_writew),
544 static driver_t imcsmb_driver = {
546 .methods = imcsmb_methods,
547 .size = sizeof(struct imcsmb_softc),
550 DRIVER_MODULE(imcsmb, imcsmb_pci, imcsmb_driver, imcsmb_devclass, 0, 0);
551 MODULE_DEPEND(imcsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
552 MODULE_VERSION(imcsmb, 1);
554 DRIVER_MODULE(smbus, imcsmb, smbus_driver, smbus_devclass, 0, 0);
556 /* vi: set ts=8 sw=4 sts=8 noet: */