xref: /freebsd/sys/dev/ismt/ismt.c (revision 18250ec6c089c0c50cbd9fd87d78e03ff89916df)
1 /*-
2  * Copyright (C) 2014 Intel Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of Intel Corporation nor the names of its
14  *    contributors may be used to endorse or promote products derived from
15  *    this software without specific prior written permission.
16  *
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
27  * SUCH DAMAGE.
28  */
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/bus.h>
33 #include <sys/errno.h>
34 #include <sys/kernel.h>
35 #include <sys/lock.h>
36 #include <sys/module.h>
37 #include <sys/priority.h>
38 #include <sys/proc.h>
39 #include <sys/syslog.h>
40 
41 #include <machine/bus.h>
42 #include <sys/rman.h>
43 #include <machine/resource.h>
44 
45 #include <dev/pci/pcireg.h>
46 #include <dev/pci/pcivar.h>
47 #include <dev/smbus/smbconf.h>
48 
49 #include "smbus_if.h"
50 
51 #define ISMT_DESC_ENTRIES	32
52 
53 /* Hardware Descriptor Constants - Control Field */
54 #define ISMT_DESC_CWRL	0x01	/* Command/Write Length */
55 #define ISMT_DESC_BLK	0X04	/* Perform Block Transaction */
56 #define ISMT_DESC_FAIR	0x08	/* Set fairness flag upon successful arbit. */
57 #define ISMT_DESC_PEC	0x10	/* Packet Error Code */
58 #define ISMT_DESC_I2C	0x20	/* I2C Enable */
59 #define ISMT_DESC_INT	0x40	/* Interrupt */
60 #define ISMT_DESC_SOE	0x80	/* Stop On Error */
61 
62 /* Hardware Descriptor Constants - Status Field */
63 #define ISMT_DESC_SCS	0x01	/* Success */
64 #define ISMT_DESC_DLTO	0x04	/* Data Low Time Out */
65 #define ISMT_DESC_NAK	0x08	/* NAK Received */
66 #define ISMT_DESC_CRC	0x10	/* CRC Error */
67 #define ISMT_DESC_CLTO	0x20	/* Clock Low Time Out */
68 #define ISMT_DESC_COL	0x40	/* Collisions */
69 #define ISMT_DESC_LPR	0x80	/* Large Packet Received */
70 
71 /* Macros */
72 #define ISMT_DESC_ADDR_RW(addr, is_read) ((addr) | (is_read))
73 
74 /* iSMT General Register address offsets (SMBBAR + <addr>) */
75 #define ISMT_GR_GCTRL		0x000	/* General Control */
76 #define ISMT_GR_SMTICL		0x008	/* SMT Interrupt Cause Location */
77 #define ISMT_GR_ERRINTMSK	0x010	/* Error Interrupt Mask */
78 #define ISMT_GR_ERRAERMSK	0x014	/* Error AER Mask */
79 #define ISMT_GR_ERRSTS		0x018	/* Error Status */
80 #define ISMT_GR_ERRINFO		0x01c	/* Error Information */
81 
82 /* iSMT Master Registers */
83 #define ISMT_MSTR_MDBA		0x100	/* Master Descriptor Base Address */
84 #define ISMT_MSTR_MCTRL		0x108	/* Master Control */
85 #define ISMT_MSTR_MSTS		0x10c	/* Master Status */
86 #define ISMT_MSTR_MDS		0x110	/* Master Descriptor Size */
87 #define ISMT_MSTR_RPOLICY	0x114	/* Retry Policy */
88 
89 /* iSMT Miscellaneous Registers */
90 #define ISMT_SPGT	0x300	/* SMBus PHY Global Timing */
91 
92 /* General Control Register (GCTRL) bit definitions */
93 #define ISMT_GCTRL_TRST	0x04	/* Target Reset */
94 #define ISMT_GCTRL_KILL	0x08	/* Kill */
95 #define ISMT_GCTRL_SRST	0x40	/* Soft Reset */
96 
97 /* Master Control Register (MCTRL) bit definitions */
98 #define ISMT_MCTRL_SS	0x01		/* Start/Stop */
99 #define ISMT_MCTRL_MEIE	0x10		/* Master Error Interrupt Enable */
100 #define ISMT_MCTRL_FMHP	0x00ff0000	/* Firmware Master Head Ptr (FMHP) */
101 
102 /* Master Status Register (MSTS) bit definitions */
103 #define ISMT_MSTS_HMTP	0xff0000	/* HW Master Tail Pointer (HMTP) */
104 #define ISMT_MSTS_MIS	0x20		/* Master Interrupt Status (MIS) */
105 #define ISMT_MSTS_MEIS	0x10		/* Master Error Int Status (MEIS) */
106 #define ISMT_MSTS_IP	0x01		/* In Progress */
107 
108 /* Master Descriptor Size (MDS) bit definitions */
109 #define ISMT_MDS_MASK	0xff	/* Master Descriptor Size mask (MDS) */
110 
111 /* SMBus PHY Global Timing Register (SPGT) bit definitions */
112 #define ISMT_SPGT_SPD_MASK	0xc0000000	/* SMBus Speed mask */
113 #define ISMT_SPGT_SPD_80K	0x00		/* 80 kHz */
114 #define ISMT_SPGT_SPD_100K	(0x1 << 30)	/* 100 kHz */
115 #define ISMT_SPGT_SPD_400K	(0x2 << 30)	/* 400 kHz */
116 #define ISMT_SPGT_SPD_1M	(0x3 << 30)	/* 1 MHz */
117 
118 /* MSI Control Register (MSICTL) bit definitions */
119 #define ISMT_MSICTL_MSIE	0x01	/* MSI Enable */
120 
121 #define ISMT_MAX_BLOCK_SIZE	32 /* per SMBus spec */
122 
123 //#define ISMT_DEBUG	device_printf
124 #ifndef ISMT_DEBUG
125 #define ISMT_DEBUG(...)
126 #endif
127 
128 /* iSMT Hardware Descriptor */
129 struct ismt_desc {
130 	uint8_t tgtaddr_rw;	/* target address & r/w bit */
131 	uint8_t wr_len_cmd;	/* write length in bytes or a command */
132 	uint8_t rd_len;		/* read length */
133 	uint8_t control;	/* control bits */
134 	uint8_t status;		/* status bits */
135 	uint8_t retry;		/* collision retry and retry count */
136 	uint8_t rxbytes;	/* received bytes */
137 	uint8_t txbytes;	/* transmitted bytes */
138 	uint32_t dptr_low;	/* lower 32 bit of the data pointer */
139 	uint32_t dptr_high;	/* upper 32 bit of the data pointer */
140 } __packed;
141 
142 #define DESC_SIZE	(ISMT_DESC_ENTRIES * sizeof(struct ismt_desc))
143 
144 #define DMA_BUFFER_SIZE	64
145 
146 struct ismt_softc {
147 	device_t		pcidev;
148 	device_t		smbdev;
149 
150 	struct thread		*bus_reserved;
151 
152 	int			intr_rid;
153 	struct resource		*intr_res;
154 	void			*intr_handle;
155 
156 	bus_space_tag_t		mmio_tag;
157 	bus_space_handle_t	mmio_handle;
158 	int			mmio_rid;
159 	struct resource		*mmio_res;
160 
161 	uint8_t			head;
162 
163 	struct ismt_desc	*desc;
164 	bus_dma_tag_t		desc_dma_tag;
165 	bus_dmamap_t		desc_dma_map;
166 	uint64_t		desc_bus_addr;
167 
168 	uint8_t			*dma_buffer;
169 	bus_dma_tag_t		dma_buffer_dma_tag;
170 	bus_dmamap_t		dma_buffer_dma_map;
171 	uint64_t		dma_buffer_bus_addr;
172 
173 	uint8_t			using_msi;
174 };
175 
176 static void
ismt_intr(void * arg)177 ismt_intr(void *arg)
178 {
179 	struct ismt_softc *sc = arg;
180 	uint32_t val;
181 
182 	val = bus_read_4(sc->mmio_res, ISMT_MSTR_MSTS);
183 	ISMT_DEBUG(sc->pcidev, "%s MSTS=0x%x\n", __func__, val);
184 
185 	val |= (ISMT_MSTS_MIS | ISMT_MSTS_MEIS);
186 	bus_write_4(sc->mmio_res, ISMT_MSTR_MSTS, val);
187 
188 	wakeup(sc);
189 }
190 
191 static int
ismt_callback(device_t dev,int index,void * data)192 ismt_callback(device_t dev, int index, void *data)
193 {
194 	struct ismt_softc	*sc;
195 	int			acquired, err;
196 
197 	sc = device_get_softc(dev);
198 
199 	switch (index) {
200 	case SMB_REQUEST_BUS:
201 		acquired = atomic_cmpset_ptr(
202 		    (uintptr_t *)&sc->bus_reserved,
203 		    (uintptr_t)NULL, (uintptr_t)curthread);
204 		ISMT_DEBUG(dev, "SMB_REQUEST_BUS acquired=%d\n", acquired);
205 		if (acquired)
206 			err = 0;
207 		else
208 			err = EWOULDBLOCK;
209 		break;
210 	case SMB_RELEASE_BUS:
211 		KASSERT(sc->bus_reserved == curthread,
212 		    ("SMB_RELEASE_BUS called by wrong thread\n"));
213 		ISMT_DEBUG(dev, "SMB_RELEASE_BUS\n");
214 		atomic_store_rel_ptr((uintptr_t *)&sc->bus_reserved,
215 		    (uintptr_t)NULL);
216 		err = 0;
217 		break;
218 	default:
219 		err = SMB_EABORT;
220 		break;
221 	}
222 
223 	return (err);
224 }
225 
226 static struct ismt_desc *
ismt_alloc_desc(struct ismt_softc * sc)227 ismt_alloc_desc(struct ismt_softc *sc)
228 {
229 	struct ismt_desc *desc;
230 
231 	KASSERT(sc->bus_reserved == curthread,
232 	    ("curthread %p did not request bus (%p has reserved)\n",
233 	    curthread, sc->bus_reserved));
234 
235 	desc = &sc->desc[sc->head++];
236 	if (sc->head == ISMT_DESC_ENTRIES)
237 		sc->head = 0;
238 
239 	memset(desc, 0, sizeof(*desc));
240 
241 	return (desc);
242 }
243 
244 static int
ismt_submit(struct ismt_softc * sc,struct ismt_desc * desc,uint8_t slave,uint8_t is_read)245 ismt_submit(struct ismt_softc *sc, struct ismt_desc *desc, uint8_t slave,
246     uint8_t is_read)
247 {
248 	uint32_t err, fmhp, val;
249 
250 	desc->control |= ISMT_DESC_FAIR;
251 	if (sc->using_msi)
252 		desc->control |= ISMT_DESC_INT;
253 
254 	desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(slave, is_read);
255 	desc->dptr_low = (sc->dma_buffer_bus_addr & 0xFFFFFFFFLL);
256 	desc->dptr_high = (sc->dma_buffer_bus_addr >> 32);
257 
258 	wmb();
259 
260 	fmhp = sc->head << 16;
261 	val = bus_read_4(sc->mmio_res, ISMT_MSTR_MCTRL);
262 	val &= ~ISMT_MCTRL_FMHP;
263 	val |= fmhp;
264 	bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, val);
265 
266 	/* set the start bit */
267 	val = bus_read_4(sc->mmio_res, ISMT_MSTR_MCTRL);
268 	val |= ISMT_MCTRL_SS;
269 	bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, val);
270 
271 	err = tsleep(sc, PWAIT, "ismt_wait", 5 * hz);
272 
273 	if (err != 0) {
274 		ISMT_DEBUG(sc->pcidev, "%s timeout\n", __func__);
275 		return (SMB_ETIMEOUT);
276 	}
277 
278 	ISMT_DEBUG(sc->pcidev, "%s status=0x%x\n", __func__, desc->status);
279 
280 	if (desc->status & ISMT_DESC_SCS)
281 		return (SMB_ENOERR);
282 
283 	if (desc->status & ISMT_DESC_NAK)
284 		return (SMB_ENOACK);
285 
286 	if (desc->status & ISMT_DESC_CRC)
287 		return (SMB_EBUSERR);
288 
289 	if (desc->status & ISMT_DESC_COL)
290 		return (SMB_ECOLLI);
291 
292 	if (desc->status & ISMT_DESC_LPR)
293 		return (SMB_EINVAL);
294 
295 	if (desc->status & (ISMT_DESC_DLTO | ISMT_DESC_CLTO))
296 		return (SMB_ETIMEOUT);
297 
298 	return (SMB_EBUSERR);
299 }
300 
301 
302 static int
ismt_quick(device_t dev,u_char slave,int how)303 ismt_quick(device_t dev, u_char slave, int how)
304 {
305 	struct ismt_desc	*desc;
306 	struct ismt_softc	*sc;
307 	int			is_read;
308 
309 	ISMT_DEBUG(dev, "%s\n", __func__);
310 
311 	if (how != SMB_QREAD && how != SMB_QWRITE) {
312 		return (SMB_ENOTSUPP);
313 	}
314 
315 	sc = device_get_softc(dev);
316 	desc = ismt_alloc_desc(sc);
317 	is_read = (how == SMB_QREAD ? 1 : 0);
318 	return (ismt_submit(sc, desc, slave, is_read));
319 }
320 
321 static int
ismt_sendb(device_t dev,u_char slave,char byte)322 ismt_sendb(device_t dev, u_char slave, char byte)
323 {
324 	struct ismt_desc	*desc;
325 	struct ismt_softc	*sc;
326 
327 	ISMT_DEBUG(dev, "%s\n", __func__);
328 
329 	sc = device_get_softc(dev);
330 	desc = ismt_alloc_desc(sc);
331 	desc->control = ISMT_DESC_CWRL;
332 	desc->wr_len_cmd = byte;
333 
334 	return (ismt_submit(sc, desc, slave, 0));
335 }
336 
337 static int
ismt_recvb(device_t dev,u_char slave,char * byte)338 ismt_recvb(device_t dev, u_char slave, char *byte)
339 {
340 	struct ismt_desc	*desc;
341 	struct ismt_softc	*sc;
342 	int			err;
343 
344 	ISMT_DEBUG(dev, "%s\n", __func__);
345 
346 	sc = device_get_softc(dev);
347 	desc = ismt_alloc_desc(sc);
348 	desc->rd_len = 1;
349 
350 	err = ismt_submit(sc, desc, slave, 1);
351 
352 	if (err != SMB_ENOERR)
353 		return (err);
354 
355 	*byte = sc->dma_buffer[0];
356 
357 	return (err);
358 }
359 
360 static int
ismt_writeb(device_t dev,u_char slave,char cmd,char byte)361 ismt_writeb(device_t dev, u_char slave, char cmd, char byte)
362 {
363 	struct ismt_desc	*desc;
364 	struct ismt_softc	*sc;
365 
366 	ISMT_DEBUG(dev, "%s\n", __func__);
367 
368 	sc = device_get_softc(dev);
369 	desc = ismt_alloc_desc(sc);
370 	desc->wr_len_cmd = 2;
371 	sc->dma_buffer[0] = cmd;
372 	sc->dma_buffer[1] = byte;
373 
374 	return (ismt_submit(sc, desc, slave, 0));
375 }
376 
377 static int
ismt_writew(device_t dev,u_char slave,char cmd,short word)378 ismt_writew(device_t dev, u_char slave, char cmd, short word)
379 {
380 	struct ismt_desc	*desc;
381 	struct ismt_softc	*sc;
382 
383 	ISMT_DEBUG(dev, "%s\n", __func__);
384 
385 	sc = device_get_softc(dev);
386 	desc = ismt_alloc_desc(sc);
387 	desc->wr_len_cmd = 3;
388 	sc->dma_buffer[0] = cmd;
389 	sc->dma_buffer[1] = word & 0xFF;
390 	sc->dma_buffer[2] = word >> 8;
391 
392 	return (ismt_submit(sc, desc, slave, 0));
393 }
394 
395 static int
ismt_readb(device_t dev,u_char slave,char cmd,char * byte)396 ismt_readb(device_t dev, u_char slave, char cmd, char *byte)
397 {
398 	struct ismt_desc	*desc;
399 	struct ismt_softc	*sc;
400 	int			err;
401 
402 	ISMT_DEBUG(dev, "%s\n", __func__);
403 
404 	sc = device_get_softc(dev);
405 	desc = ismt_alloc_desc(sc);
406 	desc->control = ISMT_DESC_CWRL;
407 	desc->wr_len_cmd = cmd;
408 	desc->rd_len = 1;
409 
410 	err = ismt_submit(sc, desc, slave, 1);
411 
412 	if (err != SMB_ENOERR)
413 		return (err);
414 
415 	*byte = sc->dma_buffer[0];
416 
417 	return (err);
418 }
419 
420 static int
ismt_readw(device_t dev,u_char slave,char cmd,short * word)421 ismt_readw(device_t dev, u_char slave, char cmd, short *word)
422 {
423 	struct ismt_desc	*desc;
424 	struct ismt_softc	*sc;
425 	int			err;
426 
427 	ISMT_DEBUG(dev, "%s\n", __func__);
428 
429 	sc = device_get_softc(dev);
430 	desc = ismt_alloc_desc(sc);
431 	desc->control = ISMT_DESC_CWRL;
432 	desc->wr_len_cmd = cmd;
433 	desc->rd_len = 2;
434 
435 	err = ismt_submit(sc, desc, slave, 1);
436 
437 	if (err != SMB_ENOERR)
438 		return (err);
439 
440 	*word = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8);
441 
442 	return (err);
443 }
444 
445 static int
ismt_pcall(device_t dev,u_char slave,char cmd,short sdata,short * rdata)446 ismt_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata)
447 {
448 	struct ismt_desc	*desc;
449 	struct ismt_softc	*sc;
450 	int			err;
451 
452 	ISMT_DEBUG(dev, "%s\n", __func__);
453 
454 	sc = device_get_softc(dev);
455 	desc = ismt_alloc_desc(sc);
456 	desc->wr_len_cmd = 3;
457 	desc->rd_len = 2;
458 	sc->dma_buffer[0] = cmd;
459 	sc->dma_buffer[1] = sdata & 0xff;
460 	sc->dma_buffer[2] = sdata >> 8;
461 
462 	err = ismt_submit(sc, desc, slave, 0);
463 
464 	if (err != SMB_ENOERR)
465 		return (err);
466 
467 	*rdata = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8);
468 
469 	return (err);
470 }
471 
472 static int
ismt_bwrite(device_t dev,u_char slave,char cmd,u_char count,char * buf)473 ismt_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
474 {
475 	struct ismt_desc	*desc;
476 	struct ismt_softc	*sc;
477 
478 	ISMT_DEBUG(dev, "%s\n", __func__);
479 
480 	if (count == 0 || count > ISMT_MAX_BLOCK_SIZE)
481 		return (SMB_EINVAL);
482 
483 	sc = device_get_softc(dev);
484 	desc = ismt_alloc_desc(sc);
485 	desc->control = ISMT_DESC_I2C;
486 	desc->wr_len_cmd = count + 1;
487 	sc->dma_buffer[0] = cmd;
488 	memcpy(&sc->dma_buffer[1], buf, count);
489 
490 	return (ismt_submit(sc, desc, slave, 0));
491 }
492 
493 static int
ismt_bread(device_t dev,u_char slave,char cmd,u_char * count,char * buf)494 ismt_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
495 {
496 	struct ismt_desc	*desc;
497 	struct ismt_softc	*sc;
498 	int			err;
499 
500 	ISMT_DEBUG(dev, "%s\n", __func__);
501 
502 	if (*count == 0 || *count > ISMT_MAX_BLOCK_SIZE)
503 		return (SMB_EINVAL);
504 
505 	sc = device_get_softc(dev);
506 	desc = ismt_alloc_desc(sc);
507 	desc->control = ISMT_DESC_I2C | ISMT_DESC_CWRL;
508 	desc->wr_len_cmd = cmd;
509 	desc->rd_len = *count;
510 
511 	err = ismt_submit(sc, desc, slave, 0);
512 
513 	if (err != SMB_ENOERR)
514 		return (err);
515 
516 	memcpy(buf, sc->dma_buffer, desc->rxbytes);
517 	*count = desc->rxbytes;
518 
519 	return (err);
520 }
521 
522 static int
ismt_detach(device_t dev)523 ismt_detach(device_t dev)
524 {
525 	struct ismt_softc	*sc;
526 	int			error;
527 
528 	ISMT_DEBUG(dev, "%s\n", __func__);
529 	sc = device_get_softc(dev);
530 
531 	error = bus_generic_detach(dev);
532 	if (error)
533 		return (error);
534 
535 	device_delete_child(dev, sc->smbdev);
536 
537 	if (sc->intr_handle != NULL) {
538 		bus_teardown_intr(dev, sc->intr_res, sc->intr_handle);
539 		sc->intr_handle = NULL;
540 	}
541 	if (sc->intr_res != NULL) {
542 		bus_release_resource(dev,
543 		    SYS_RES_IRQ, sc->intr_rid, sc->intr_res);
544 		sc->intr_res = NULL;
545 	}
546 	if (sc->using_msi == 1)
547 		pci_release_msi(dev);
548 
549 	if (sc->mmio_res != NULL) {
550 		bus_release_resource(dev,
551 		    SYS_RES_MEMORY, sc->mmio_rid, sc->mmio_res);
552 		sc->mmio_res = NULL;
553 	}
554 
555 	bus_dmamap_unload(sc->desc_dma_tag, sc->desc_dma_map);
556 	bus_dmamap_unload(sc->dma_buffer_dma_tag, sc->dma_buffer_dma_map);
557 
558 	bus_dmamem_free(sc->desc_dma_tag, sc->desc,
559 	    sc->desc_dma_map);
560 	bus_dmamem_free(sc->dma_buffer_dma_tag, sc->dma_buffer,
561 	    sc->dma_buffer_dma_map);
562 
563 	bus_dma_tag_destroy(sc->desc_dma_tag);
564 	bus_dma_tag_destroy(sc->dma_buffer_dma_tag);
565 
566 	pci_disable_busmaster(dev);
567 
568 	return 0;
569 }
570 
571 static void
ismt_single_map(void * arg,bus_dma_segment_t * seg,int nseg,int error)572 ismt_single_map(void *arg, bus_dma_segment_t *seg, int nseg, int error)
573 {
574 	uint64_t *bus_addr = (uint64_t *)arg;
575 
576 	KASSERT(error == 0, ("%s: error=%d\n", __func__, error));
577 	KASSERT(nseg == 1, ("%s: nseg=%d\n", __func__, nseg));
578 
579 	*bus_addr = seg[0].ds_addr;
580 }
581 
582 static int
ismt_attach(device_t dev)583 ismt_attach(device_t dev)
584 {
585 	struct ismt_softc *sc = device_get_softc(dev);
586 	int err, num_vectors, val;
587 
588 	sc->pcidev = dev;
589 	pci_enable_busmaster(dev);
590 
591 	if ((sc->smbdev = device_add_child(dev, "smbus", -1)) == NULL) {
592 		device_printf(dev, "no smbus child found\n");
593 		err = ENXIO;
594 		goto fail;
595 	}
596 
597 	sc->mmio_rid = PCIR_BAR(0);
598 	sc->mmio_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
599 	    &sc->mmio_rid, RF_ACTIVE);
600 	if (sc->mmio_res == NULL) {
601 		device_printf(dev, "cannot allocate mmio region\n");
602 		err = ENOMEM;
603 		goto fail;
604 	}
605 
606 	sc->mmio_tag = rman_get_bustag(sc->mmio_res);
607 	sc->mmio_handle = rman_get_bushandle(sc->mmio_res);
608 
609 	/* Attach "smbus" child */
610 	bus_attach_children(dev);
611 
612 	bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE,
613 	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
614 	    DESC_SIZE, 1, DESC_SIZE,
615 	    0, NULL, NULL, &sc->desc_dma_tag);
616 
617 	bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE,
618 	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
619 	    DMA_BUFFER_SIZE, 1, DMA_BUFFER_SIZE,
620 	    0, NULL, NULL, &sc->dma_buffer_dma_tag);
621 
622 	bus_dmamap_create(sc->desc_dma_tag, 0,
623 	    &sc->desc_dma_map);
624 	bus_dmamap_create(sc->dma_buffer_dma_tag, 0,
625 	    &sc->dma_buffer_dma_map);
626 
627 	bus_dmamem_alloc(sc->desc_dma_tag,
628 	    (void **)&sc->desc, BUS_DMA_WAITOK,
629 	    &sc->desc_dma_map);
630 	bus_dmamem_alloc(sc->dma_buffer_dma_tag,
631 	    (void **)&sc->dma_buffer, BUS_DMA_WAITOK,
632 	    &sc->dma_buffer_dma_map);
633 
634 	bus_dmamap_load(sc->desc_dma_tag,
635 	    sc->desc_dma_map, sc->desc, DESC_SIZE,
636 	    ismt_single_map, &sc->desc_bus_addr, 0);
637 	bus_dmamap_load(sc->dma_buffer_dma_tag,
638 	    sc->dma_buffer_dma_map, sc->dma_buffer, DMA_BUFFER_SIZE,
639 	    ismt_single_map, &sc->dma_buffer_bus_addr, 0);
640 
641 	bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA,
642 	    (sc->desc_bus_addr & 0xFFFFFFFFLL));
643 	bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA + 4,
644 	    (sc->desc_bus_addr >> 32));
645 
646 	/* initialize the Master Control Register (MCTRL) */
647 	bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, ISMT_MCTRL_MEIE);
648 
649 	/* initialize the Master Status Register (MSTS) */
650 	bus_write_4(sc->mmio_res, ISMT_MSTR_MSTS, 0);
651 
652 	/* initialize the Master Descriptor Size (MDS) */
653 	val = bus_read_4(sc->mmio_res, ISMT_MSTR_MDS);
654 	val &= ~ISMT_MDS_MASK;
655 	val |= (ISMT_DESC_ENTRIES - 1);
656 	bus_write_4(sc->mmio_res, ISMT_MSTR_MDS, val);
657 
658 	sc->using_msi = 1;
659 
660 	if (pci_msi_count(dev) == 0) {
661 		sc->using_msi = 0;
662 		goto intx;
663 	}
664 
665 	num_vectors = 1;
666 	if (pci_alloc_msi(dev, &num_vectors) != 0) {
667 		sc->using_msi = 0;
668 		goto intx;
669 	}
670 
671 	sc->intr_rid = 1;
672 	sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
673 	    &sc->intr_rid, RF_ACTIVE);
674 
675 	if (sc->intr_res == NULL) {
676 		sc->using_msi = 0;
677 		pci_release_msi(dev);
678 	}
679 
680 intx:
681 	if (sc->using_msi == 0) {
682 		sc->intr_rid = 0;
683 		sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
684 		    &sc->intr_rid, RF_SHAREABLE | RF_ACTIVE);
685 		if (sc->intr_res == NULL) {
686 			device_printf(dev, "cannot allocate irq\n");
687 			err = ENXIO;
688 			goto fail;
689 		}
690 	}
691 
692 	ISMT_DEBUG(dev, "using_msi = %d\n", sc->using_msi);
693 
694 	err = bus_setup_intr(dev, sc->intr_res,
695 	    INTR_TYPE_MISC | INTR_MPSAFE, NULL, ismt_intr, sc,
696 	    &sc->intr_handle);
697 	if (err != 0) {
698 		device_printf(dev, "cannot setup interrupt\n");
699 		err = ENXIO;
700 		goto fail;
701 	}
702 
703 	return (0);
704 
705 fail:
706 	ismt_detach(dev);
707 	return (err);
708 }
709 
710 #define ID_INTEL_S1200_SMT0		0x0c598086
711 #define ID_INTEL_S1200_SMT1		0x0c5a8086
712 #define ID_INTEL_C2000_SMT		0x1f158086
713 #define ID_INTEL_C3000_SMT		0x19ac8086
714 
715 static int
ismt_probe(device_t dev)716 ismt_probe(device_t dev)
717 {
718 	const char *desc;
719 
720 	switch (pci_get_devid(dev)) {
721 	case ID_INTEL_S1200_SMT0:
722 		desc = "Atom Processor S1200 SMBus 2.0 Controller 0";
723 		break;
724 	case ID_INTEL_S1200_SMT1:
725 		desc = "Atom Processor S1200 SMBus 2.0 Controller 1";
726 		break;
727 	case ID_INTEL_C2000_SMT:
728 		desc = "Atom Processor C2000 SMBus 2.0";
729 		break;
730 	case ID_INTEL_C3000_SMT:
731 		desc = "Atom Processor C3000 SMBus 2.0";
732 		break;
733 	default:
734 		return (ENXIO);
735 	}
736 
737 	device_set_desc(dev, desc);
738 	return (BUS_PROBE_DEFAULT);
739 }
740 
741 /* Device methods */
742 static device_method_t ismt_pci_methods[] = {
743         DEVMETHOD(device_probe,		ismt_probe),
744         DEVMETHOD(device_attach,	ismt_attach),
745         DEVMETHOD(device_detach,	ismt_detach),
746 
747         DEVMETHOD(smbus_callback,	ismt_callback),
748         DEVMETHOD(smbus_quick,		ismt_quick),
749         DEVMETHOD(smbus_sendb,		ismt_sendb),
750         DEVMETHOD(smbus_recvb,		ismt_recvb),
751         DEVMETHOD(smbus_writeb,		ismt_writeb),
752         DEVMETHOD(smbus_writew,		ismt_writew),
753         DEVMETHOD(smbus_readb,		ismt_readb),
754         DEVMETHOD(smbus_readw,		ismt_readw),
755         DEVMETHOD(smbus_pcall,		ismt_pcall),
756         DEVMETHOD(smbus_bwrite,		ismt_bwrite),
757         DEVMETHOD(smbus_bread,		ismt_bread),
758 
759 	DEVMETHOD_END
760 };
761 
762 static driver_t ismt_pci_driver = {
763 	"ismt",
764 	ismt_pci_methods,
765 	sizeof(struct ismt_softc)
766 };
767 
768 DRIVER_MODULE(ismt, pci, ismt_pci_driver, 0, 0);
769 DRIVER_MODULE(smbus, ismt, smbus_driver, 0, 0);
770 
771 MODULE_DEPEND(ismt, pci, 1, 1, 1);
772 MODULE_DEPEND(ismt, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
773 MODULE_VERSION(ismt, 1);
774