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 if (sc->intr_handle != NULL) {
536 bus_teardown_intr(dev, sc->intr_res, sc->intr_handle);
537 sc->intr_handle = NULL;
538 }
539 if (sc->intr_res != NULL) {
540 bus_release_resource(dev,
541 SYS_RES_IRQ, sc->intr_rid, sc->intr_res);
542 sc->intr_res = NULL;
543 }
544 if (sc->using_msi == 1)
545 pci_release_msi(dev);
546
547 if (sc->mmio_res != NULL) {
548 bus_release_resource(dev,
549 SYS_RES_MEMORY, sc->mmio_rid, sc->mmio_res);
550 sc->mmio_res = NULL;
551 }
552
553 bus_dmamap_unload(sc->desc_dma_tag, sc->desc_dma_map);
554 bus_dmamap_unload(sc->dma_buffer_dma_tag, sc->dma_buffer_dma_map);
555
556 bus_dmamem_free(sc->desc_dma_tag, sc->desc,
557 sc->desc_dma_map);
558 bus_dmamem_free(sc->dma_buffer_dma_tag, sc->dma_buffer,
559 sc->dma_buffer_dma_map);
560
561 bus_dma_tag_destroy(sc->desc_dma_tag);
562 bus_dma_tag_destroy(sc->dma_buffer_dma_tag);
563
564 pci_disable_busmaster(dev);
565
566 return 0;
567 }
568
569 static void
ismt_single_map(void * arg,bus_dma_segment_t * seg,int nseg,int error)570 ismt_single_map(void *arg, bus_dma_segment_t *seg, int nseg, int error)
571 {
572 uint64_t *bus_addr = (uint64_t *)arg;
573
574 KASSERT(error == 0, ("%s: error=%d\n", __func__, error));
575 KASSERT(nseg == 1, ("%s: nseg=%d\n", __func__, nseg));
576
577 *bus_addr = seg[0].ds_addr;
578 }
579
580 static int
ismt_attach(device_t dev)581 ismt_attach(device_t dev)
582 {
583 struct ismt_softc *sc = device_get_softc(dev);
584 int err, num_vectors, val;
585
586 sc->pcidev = dev;
587 pci_enable_busmaster(dev);
588
589 if ((sc->smbdev = device_add_child(dev, "smbus",
590 DEVICE_UNIT_ANY)) == NULL) {
591 device_printf(dev, "no smbus child found\n");
592 err = ENXIO;
593 goto fail;
594 }
595
596 sc->mmio_rid = PCIR_BAR(0);
597 sc->mmio_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
598 &sc->mmio_rid, RF_ACTIVE);
599 if (sc->mmio_res == NULL) {
600 device_printf(dev, "cannot allocate mmio region\n");
601 err = ENOMEM;
602 goto fail;
603 }
604
605 sc->mmio_tag = rman_get_bustag(sc->mmio_res);
606 sc->mmio_handle = rman_get_bushandle(sc->mmio_res);
607
608 /* Attach "smbus" child */
609 bus_attach_children(dev);
610
611 bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE,
612 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
613 DESC_SIZE, 1, DESC_SIZE,
614 0, NULL, NULL, &sc->desc_dma_tag);
615
616 bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE,
617 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
618 DMA_BUFFER_SIZE, 1, DMA_BUFFER_SIZE,
619 0, NULL, NULL, &sc->dma_buffer_dma_tag);
620
621 bus_dmamap_create(sc->desc_dma_tag, 0,
622 &sc->desc_dma_map);
623 bus_dmamap_create(sc->dma_buffer_dma_tag, 0,
624 &sc->dma_buffer_dma_map);
625
626 bus_dmamem_alloc(sc->desc_dma_tag,
627 (void **)&sc->desc, BUS_DMA_WAITOK,
628 &sc->desc_dma_map);
629 bus_dmamem_alloc(sc->dma_buffer_dma_tag,
630 (void **)&sc->dma_buffer, BUS_DMA_WAITOK,
631 &sc->dma_buffer_dma_map);
632
633 bus_dmamap_load(sc->desc_dma_tag,
634 sc->desc_dma_map, sc->desc, DESC_SIZE,
635 ismt_single_map, &sc->desc_bus_addr, 0);
636 bus_dmamap_load(sc->dma_buffer_dma_tag,
637 sc->dma_buffer_dma_map, sc->dma_buffer, DMA_BUFFER_SIZE,
638 ismt_single_map, &sc->dma_buffer_bus_addr, 0);
639
640 bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA,
641 (sc->desc_bus_addr & 0xFFFFFFFFLL));
642 bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA + 4,
643 (sc->desc_bus_addr >> 32));
644
645 /* initialize the Master Control Register (MCTRL) */
646 bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, ISMT_MCTRL_MEIE);
647
648 /* initialize the Master Status Register (MSTS) */
649 bus_write_4(sc->mmio_res, ISMT_MSTR_MSTS, 0);
650
651 /* initialize the Master Descriptor Size (MDS) */
652 val = bus_read_4(sc->mmio_res, ISMT_MSTR_MDS);
653 val &= ~ISMT_MDS_MASK;
654 val |= (ISMT_DESC_ENTRIES - 1);
655 bus_write_4(sc->mmio_res, ISMT_MSTR_MDS, val);
656
657 sc->using_msi = 1;
658
659 if (pci_msi_count(dev) == 0) {
660 sc->using_msi = 0;
661 goto intx;
662 }
663
664 num_vectors = 1;
665 if (pci_alloc_msi(dev, &num_vectors) != 0) {
666 sc->using_msi = 0;
667 goto intx;
668 }
669
670 sc->intr_rid = 1;
671 sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
672 &sc->intr_rid, RF_ACTIVE);
673
674 if (sc->intr_res == NULL) {
675 sc->using_msi = 0;
676 pci_release_msi(dev);
677 }
678
679 intx:
680 if (sc->using_msi == 0) {
681 sc->intr_rid = 0;
682 sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
683 &sc->intr_rid, RF_SHAREABLE | RF_ACTIVE);
684 if (sc->intr_res == NULL) {
685 device_printf(dev, "cannot allocate irq\n");
686 err = ENXIO;
687 goto fail;
688 }
689 }
690
691 ISMT_DEBUG(dev, "using_msi = %d\n", sc->using_msi);
692
693 err = bus_setup_intr(dev, sc->intr_res,
694 INTR_TYPE_MISC | INTR_MPSAFE, NULL, ismt_intr, sc,
695 &sc->intr_handle);
696 if (err != 0) {
697 device_printf(dev, "cannot setup interrupt\n");
698 err = ENXIO;
699 goto fail;
700 }
701
702 return (0);
703
704 fail:
705 ismt_detach(dev);
706 return (err);
707 }
708
709 #define ID_INTEL_S1200_SMT0 0x0c598086
710 #define ID_INTEL_S1200_SMT1 0x0c5a8086
711 #define ID_INTEL_C2000_SMT 0x1f158086
712 #define ID_INTEL_C3000_SMT 0x19ac8086
713
714 static int
ismt_probe(device_t dev)715 ismt_probe(device_t dev)
716 {
717 const char *desc;
718
719 switch (pci_get_devid(dev)) {
720 case ID_INTEL_S1200_SMT0:
721 desc = "Atom Processor S1200 SMBus 2.0 Controller 0";
722 break;
723 case ID_INTEL_S1200_SMT1:
724 desc = "Atom Processor S1200 SMBus 2.0 Controller 1";
725 break;
726 case ID_INTEL_C2000_SMT:
727 desc = "Atom Processor C2000 SMBus 2.0";
728 break;
729 case ID_INTEL_C3000_SMT:
730 desc = "Atom Processor C3000 SMBus 2.0";
731 break;
732 default:
733 return (ENXIO);
734 }
735
736 device_set_desc(dev, desc);
737 return (BUS_PROBE_DEFAULT);
738 }
739
740 /* Device methods */
741 static device_method_t ismt_pci_methods[] = {
742 DEVMETHOD(device_probe, ismt_probe),
743 DEVMETHOD(device_attach, ismt_attach),
744 DEVMETHOD(device_detach, ismt_detach),
745
746 DEVMETHOD(smbus_callback, ismt_callback),
747 DEVMETHOD(smbus_quick, ismt_quick),
748 DEVMETHOD(smbus_sendb, ismt_sendb),
749 DEVMETHOD(smbus_recvb, ismt_recvb),
750 DEVMETHOD(smbus_writeb, ismt_writeb),
751 DEVMETHOD(smbus_writew, ismt_writew),
752 DEVMETHOD(smbus_readb, ismt_readb),
753 DEVMETHOD(smbus_readw, ismt_readw),
754 DEVMETHOD(smbus_pcall, ismt_pcall),
755 DEVMETHOD(smbus_bwrite, ismt_bwrite),
756 DEVMETHOD(smbus_bread, ismt_bread),
757
758 DEVMETHOD_END
759 };
760
761 static driver_t ismt_pci_driver = {
762 "ismt",
763 ismt_pci_methods,
764 sizeof(struct ismt_softc)
765 };
766
767 DRIVER_MODULE(ismt, pci, ismt_pci_driver, 0, 0);
768 DRIVER_MODULE(smbus, ismt, smbus_driver, 0, 0);
769
770 MODULE_DEPEND(ismt, pci, 1, 1, 1);
771 MODULE_DEPEND(ismt, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
772 MODULE_VERSION(ismt, 1);
773