xref: /freebsd/sys/dev/imcsmb/imcsmb.c (revision 4f52dfbb)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Authors: Joe Kloss; Ravi Pokala (rpokala@freebsd.org)
5  *
6  * Copyright (c) 2017-2018 Panasas
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $FreeBSD$
31  */
32 
33 /* A detailed description of this device is present in imcsmb_pci.c */
34 
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <sys/endian.h>
40 #include <sys/errno.h>
41 #include <sys/lock.h>
42 #include <sys/mutex.h>
43 #include <sys/syslog.h>
44 #include <sys/bus.h>
45 
46 #include <machine/bus.h>
47 #include <machine/atomic.h>
48 
49 #include <dev/pci/pcivar.h>
50 #include <dev/pci/pcireg.h>
51 
52 #include <dev/smbus/smbconf.h>
53 
54 #include "imcsmb_reg.h"
55 #include "imcsmb_var.h"
56 
57 /* Device methods */
58 static int imcsmb_attach(device_t dev);
59 static int imcsmb_detach(device_t dev);
60 static int imcsmb_probe(device_t dev);
61 
62 /* SMBus methods */
63 static int imcsmb_callback(device_t dev, int index, void *data);
64 static int imcsmb_readb(device_t dev, u_char slave, char cmd, char *byte);
65 static int imcsmb_readw(device_t dev, u_char slave, char cmd, short *word);
66 static int imcsmb_writeb(device_t dev, u_char slave, char cmd, char byte);
67 static int imcsmb_writew(device_t dev, u_char slave, char cmd, short word);
68 
69 /* All the read/write methods wrap around this. */
70 static int imcsmb_transfer(device_t dev, u_char slave, char cmd, void *data,
71     int word_op, int write_op);
72 
73 /**
74  * device_attach() method. Set up the softc, including getting the set of the
75  * parent imcsmb_pci's registers that we will use. Create the smbus(4) device,
76  * which any SMBus slave device drivers will connect to.
77  *
78  * @author rpokala
79  *
80  * @param[in,out] dev
81  *      Device being attached.
82  */
83 static int
84 imcsmb_attach(device_t dev)
85 {
86 	struct imcsmb_softc *sc;
87 	int rc;
88 
89 	/* Initialize private state */
90 	sc = device_get_softc(dev);
91 	sc->dev = dev;
92 	sc->imcsmb_pci = device_get_parent(dev);
93 	sc->regs = device_get_ivars(dev);
94 
95 	/* Create the smbus child */
96 	sc->smbus = device_add_child(dev, "smbus", -1);
97 	if (sc->smbus == NULL) {
98 		/* Nothing has been allocated, so there's no cleanup. */
99 		device_printf(dev, "Child smbus not added\n");
100 		rc = ENXIO;
101 		goto out;
102 	}
103 
104 	/* Attach the smbus child. */
105 	if ((rc = bus_generic_attach(dev)) != 0) {
106 		device_printf(dev, "Failed to attach smbus: %d\n", rc);
107 	}
108 
109 out:
110 	return (rc);
111 }
112 
113 /**
114  * device_detach() method. attach() didn't do any allocations, so all that's
115  * needed here is to free up any downstream drivers and children.
116  *
117  * @author Joe Kloss
118  *
119  * @param[in] dev
120  *      Device being detached.
121  */
122 static int
123 imcsmb_detach(device_t dev)
124 {
125 	int rc;
126 
127 	/* Detach any attached drivers */
128 	rc = bus_generic_detach(dev);
129 	if (rc == 0) {
130 		/* Remove all children */
131 		rc = device_delete_children(dev);
132 	}
133 
134 	return (rc);
135 }
136 
137 /**
138  * device_probe() method. All the actual probing was done by the imcsmb_pci
139  * parent, so just report success.
140  *
141  * @author Joe Kloss
142  *
143  * @param[in,out] dev
144  *      Device being probed.
145  */
146 static int
147 imcsmb_probe(device_t dev)
148 {
149 
150 	device_set_desc(dev, "iMC SMBus controller");
151 	return (BUS_PROBE_DEFAULT);
152 }
153 
154 /**
155  * smbus_callback() method. Call the parent imcsmb_pci's request or release
156  * function to quiesce / restart firmware tasks which might use the SMBus.
157  *
158  * @author rpokala
159  *
160  * @param[in] dev
161  *      Device being requested or released.
162  *
163  * @param[in] index
164  *      Either SMB_REQUEST_BUS or SMB_RELEASE_BUS.
165  *
166  * @param[in] data
167  *      Tell's the rest of the SMBus subsystem to allow or disallow waiting;
168  *      this driver only works with SMB_DONTWAIT.
169  */
170 static int
171 imcsmb_callback(device_t dev, int index, void *data)
172 {
173 	struct imcsmb_softc *sc;
174 	int *how;
175 	int rc;
176 
177 	sc = device_get_softc(dev);
178 	how = (int *) data;
179 
180 	switch (index) {
181 	case SMB_REQUEST_BUS: {
182 		if (*how != SMB_DONTWAIT) {
183 			rc = EINVAL;
184 			goto out;
185 		}
186 		rc = imcsmb_pci_request_bus(sc->imcsmb_pci);
187 		break;
188 	}
189 	case SMB_RELEASE_BUS:
190 		imcsmb_pci_release_bus(sc->imcsmb_pci);
191 		rc = 0;
192 		break;
193 	default:
194 		rc = EINVAL;
195 		break;
196 	}
197 
198 out:
199 	return (rc);
200 }
201 
202 /**
203  * smbus_readb() method. Thin wrapper around imcsmb_transfer().
204  *
205  * @author Joe Kloss
206  *
207  * @param[in] dev
208  *
209  * @param[in] slave
210  *      The SMBus address of the target device.
211  *
212  * @param[in] cmd
213  *      The SMBus command for the target device; this is the offset for SPDs,
214  *      or the register number for TSODs.
215  *
216  * @param[out] byte
217  *      The byte which was read.
218  */
219 static int
220 imcsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
221 {
222 
223 	return (imcsmb_transfer(dev, slave, cmd, byte, FALSE, FALSE));
224 }
225 
226 /**
227  * smbus_readw() method. Thin wrapper around imcsmb_transfer().
228  *
229  * @author Joe Kloss
230  *
231  * @param[in] dev
232  *
233  * @param[in] slave
234  *      The SMBus address of the target device.
235  *
236  * @param[in] cmd
237  *      The SMBus command for the target device; this is the offset for SPDs,
238  *      or the register number for TSODs.
239  *
240  * @param[out] word
241  *      The word which was read.
242  */
243 static int
244 imcsmb_readw(device_t dev, u_char slave, char cmd, short *word)
245 {
246 
247 	return (imcsmb_transfer(dev, slave, cmd, word, TRUE, FALSE));
248 }
249 
250 /**
251  * smbus_writeb() method. Thin wrapper around imcsmb_transfer().
252  *
253  * @author Joe Kloss
254  *
255  * @param[in] dev
256  *
257  * @param[in] slave
258  *      The SMBus address of the target device.
259  *
260  * @param[in] cmd
261  *      The SMBus command for the target device; this is the offset for SPDs,
262  *      or the register number for TSODs.
263  *
264  * @param[in] byte
265  *      The byte to write.
266  */
267 static int
268 imcsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
269 {
270 
271 	return (imcsmb_transfer(dev, slave, cmd, &byte, FALSE, TRUE));
272 }
273 
274 /**
275  * smbus_writew() method. Thin wrapper around imcsmb_transfer().
276  *
277  * @author Joe Kloss
278  *
279  * @param[in] dev
280  *
281  * @param[in] slave
282  *      The SMBus address of the target device.
283  *
284  * @param[in] cmd
285  *      The SMBus command for the target device; this is the offset for SPDs,
286  *      or the register number for TSODs.
287  *
288  * @param[in] word
289  *      The word to write.
290  */
291 static int
292 imcsmb_writew(device_t dev, u_char slave, char cmd, short word)
293 {
294 
295 	return (imcsmb_transfer(dev, slave, cmd, &word, TRUE, TRUE));
296 }
297 
298 /**
299  * Manipulate the PCI control registers to read data from or write data to the
300  * SMBus controller.
301  *
302  * @author Joe Kloss, rpokala
303  *
304  * @param[in] dev
305  *
306  * @param[in] slave
307  *      The SMBus address of the target device.
308  *
309  * @param[in] cmd
310  *      The SMBus command for the target device; this is the offset for SPDs,
311  *      or the register number for TSODs.
312  *
313  * @param[in,out] data
314  *      Pointer to either the value to be written, or where to place the value
315  *      which was read.
316  *
317  * @param[in] word_op
318  *      Bool: is this a word operation?
319  *
320  * @param[in] write_op
321  *      Bool: is this a write operation?
322  */
323 static int
324 imcsmb_transfer(device_t dev, u_char slave, char cmd, void *data, int word_op,
325     int write_op)
326 {
327 	struct imcsmb_softc *sc;
328 	int i;
329 	int rc;
330 	uint32_t cmd_val;
331 	uint32_t cntl_val;
332 	uint32_t orig_cntl_val;
333 	uint32_t stat_val;
334 	uint16_t *word;
335 	uint16_t lword;
336 	uint8_t *byte;
337 	uint8_t lbyte;
338 
339 	sc = device_get_softc(dev);
340 	byte = data;
341 	word = data;
342 	lbyte = *byte;
343 	lword = *word;
344 
345 	/* We modify the value of the control register; save the original, so
346 	 * we can restore it later
347 	 */
348 	orig_cntl_val = pci_read_config(sc->imcsmb_pci,
349 	    sc->regs->smb_cntl, 4);
350 	cntl_val = orig_cntl_val;
351 
352 	/*
353 	 * Set up the SMBCNTL register
354 	 */
355 
356 	/* [31:28] Clear the existing value of the DTI bits, then set them to
357 	 * the four high bits of the slave address.
358 	 */
359 	cntl_val &= ~IMCSMB_CNTL_DTI_MASK;
360 	cntl_val |= ((uint32_t) slave & 0xf0) << 24;
361 
362 	/* [27:27] Set the CLK_OVERRIDE bit, to enable normal operation */
363 	cntl_val |= IMCSMB_CNTL_CLK_OVERRIDE;
364 
365 	/* [26:26] Clear the WRITE_DISABLE bit; the datasheet says this isn't
366 	 * necessary, but empirically, it is.
367 	 */
368 	cntl_val &= ~IMCSMB_CNTL_WRITE_DISABLE_BIT;
369 
370 	/* [9:9] Clear the POLL_EN bit, to stop the hardware TSOD polling. */
371 	cntl_val &= ~IMCSMB_CNTL_POLL_EN;
372 
373 	/*
374 	 * Set up the SMBCMD register
375 	 */
376 
377 	/* [31:31] Set the TRIGGER bit; when this gets written, the controller
378 	 * will issue the command.
379 	 */
380 	cmd_val = IMCSMB_CMD_TRIGGER_BIT;
381 
382 	/* [29:29] For word operations, set the WORD_ACCESS bit. */
383 	if (word_op) {
384 		cmd_val |= IMCSMB_CMD_WORD_ACCESS;
385 	}
386 
387 	/* [27:27] For write operations, set the WRITE bit. */
388 	if (write_op) {
389 		cmd_val |= IMCSMB_CMD_WRITE_BIT;
390 	}
391 
392 	/* [26:24] The three non-DTI, non-R/W bits of the slave address. */
393 	cmd_val |= (uint32_t) ((slave & 0xe) << 23);
394 
395 	/* [23:16] The command (offset in the case of an EEPROM, or register in
396 	 * the case of TSOD or NVDIMM controller).
397 	 */
398 	cmd_val |= (uint32_t) ((uint8_t) cmd << 16);
399 
400 	/* [15:0] The data to be written for a write operation. */
401 	if (write_op) {
402 		if (word_op) {
403 			/* The datasheet says the controller uses different
404 			 * endianness for word operations on I2C vs SMBus!
405 			 *      I2C: [15:8] = MSB; [7:0] = LSB
406 			 *      SMB: [15:8] = LSB; [7:0] = MSB
407 			 * As a practical matter, this controller is very
408 			 * specifically for use with DIMMs, the SPD (and
409 			 * NVDIMM controllers) are only accessed as bytes,
410 			 * the temperature sensor is only accessed as words, and
411 			 * the temperature sensors are I2C. Thus, byte-swap the
412 			 * word.
413 			 */
414 			lword = htobe16(lword);
415 		} else {
416 			/* For byte operations, the data goes in the LSB, and
417 			 * the MSB is a don't care.
418 			 */
419 			lword = (uint16_t) (lbyte & 0xff);
420 		}
421 		cmd_val |= lword;
422 	}
423 
424 	/* Write the updated value to the control register first, to disable
425 	 * the hardware TSOD polling.
426 	 */
427 	pci_write_config(sc->imcsmb_pci, sc->regs->smb_cntl, cntl_val, 4);
428 
429 	/* Poll on the BUSY bit in the status register until clear, or timeout.
430 	 * We just cleared the auto-poll bit, so we need to make sure the device
431 	 * is idle before issuing a command. We can safely timeout after 35 ms,
432 	 * as this is the maximum time the SMBus spec allows for a transaction.
433 	 */
434 	for (i = 4; i != 0; i--) {
435 		stat_val = pci_read_config(sc->imcsmb_pci, sc->regs->smb_stat,
436 		    4);
437 		if ((stat_val & IMCSMB_STATUS_BUSY_BIT) == 0) {
438 			break;
439 		}
440 		pause("imcsmb", 10 * hz / 1000);
441 	}
442 
443 	if (i == 0) {
444 		device_printf(sc->dev,
445 		    "transfer: timeout waiting for device to settle\n");
446 	}
447 
448 	/* Now that polling has stopped, we can write the command register. This
449 	 * starts the SMBus command.
450 	 */
451 	pci_write_config(sc->imcsmb_pci, sc->regs->smb_cmd, cmd_val, 4);
452 
453 	/* Wait for WRITE_DATA_DONE/READ_DATA_VALID to be set, or timeout and
454 	 * fail. We wait up to 35ms.
455 	 */
456 	for (i = 35000; i != 0; i -= 10)
457 	{
458 		DELAY(10);
459 		stat_val = pci_read_config(sc->imcsmb_pci, sc->regs->smb_stat,
460 		    4);
461 		/* For a write, the bits holding the data contain the data being
462 		 * written. You'd think that would cause the READ_DATA_VALID bit
463 		 * to be cleared, because the data bits no longer contain valid
464 		 * data from the most recent read operation. While that would be
465 		 * logical, that's not the case here: READ_DATA_VALID is only
466 		 * cleared when starting a read operation, and WRITE_DATA_DONE
467 		 * is only cleared when starting a write operation.
468 		 */
469 		if (write_op) {
470 			if ((stat_val & IMCSMB_STATUS_WRITE_DATA_DONE) != 0) {
471 				break;
472 			}
473 		} else {
474 			if ((stat_val & IMCSMB_STATUS_READ_DATA_VALID) != 0) {
475 				break;
476 			}
477 		}
478 	}
479 	if (i == 0) {
480 		rc = SMB_ETIMEOUT;
481 		device_printf(dev, "transfer timeout\n");
482 		goto out;
483 	}
484 
485 	/* It is generally the case that this bit indicates non-ACK, but it
486 	 * could also indicate other bus errors. There's no way to tell the
487 	 * difference.
488 	 */
489 	if ((stat_val & IMCSMB_STATUS_BUS_ERROR_BIT) != 0) {
490 		/* While it is not documented, empirically, SPD page-change
491 		 * commands (writes with DTI = 0x60) always complete with the
492 		 * error bit set. So, ignore it in those cases.
493 		 */
494 		if ((slave & 0xf0) != 0x60) {
495 			rc = SMB_ENOACK;
496 			goto out;
497 		}
498 	}
499 
500 	/* For a read operation, copy the data out */
501 	if (write_op == 0) {
502 		if (word_op) {
503 			/* The data is returned in bits [15:0]; as discussed
504 			 * above, byte-swap.
505 			 */
506 			lword = (uint16_t) (stat_val & 0xffff);
507 			lword = htobe16(lword);
508 			*word = lword;
509 		} else {
510 			/* The data is returned in bits [7:0] */
511 			lbyte = (uint8_t) (stat_val & 0xff);
512 			*byte = lbyte;
513 		}
514 	}
515 
516 	/* A lack of an error is, de facto, success. */
517 	rc = SMB_ENOERR;
518 
519 out:
520 	/* Restore the original value of the control register. */
521 	pci_write_config(sc->imcsmb_pci, sc->regs->smb_cntl, orig_cntl_val, 4);
522 	return (rc);
523 }
524 
525 /* Our device class */
526 static devclass_t imcsmb_devclass;
527 
528 /* Device methods */
529 static device_method_t imcsmb_methods[] = {
530 	/* Device interface */
531 	DEVMETHOD(device_attach,	imcsmb_attach),
532 	DEVMETHOD(device_detach,	imcsmb_detach),
533 	DEVMETHOD(device_probe,		imcsmb_probe),
534 
535 	/* smbus methods */
536 	DEVMETHOD(smbus_callback,	imcsmb_callback),
537 	DEVMETHOD(smbus_readb,		imcsmb_readb),
538 	DEVMETHOD(smbus_readw,		imcsmb_readw),
539 	DEVMETHOD(smbus_writeb,		imcsmb_writeb),
540 	DEVMETHOD(smbus_writew,		imcsmb_writew),
541 
542 	DEVMETHOD_END
543 };
544 
545 static driver_t imcsmb_driver = {
546 	.name = "imcsmb",
547 	.methods = imcsmb_methods,
548 	.size = sizeof(struct imcsmb_softc),
549 };
550 
551 DRIVER_MODULE(imcsmb, imcsmb_pci, imcsmb_driver, imcsmb_devclass, 0, 0);
552 MODULE_DEPEND(imcsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
553 MODULE_VERSION(imcsmb, 1);
554 
555 DRIVER_MODULE(smbus, imcsmb, smbus_driver, smbus_devclass, 0, 0);
556 
557 /* vi: set ts=8 sw=4 sts=8 noet: */
558