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