Lines 43-55
__FBSDID("$FreeBSD$");
Link Here
|
43 |
* See ig4_var.h for locking semantics. |
43 |
* See ig4_var.h for locking semantics. |
44 |
*/ |
44 |
*/ |
45 |
|
45 |
|
|
|
46 |
#include "opt_acpi.h" |
47 |
|
46 |
#include <sys/param.h> |
48 |
#include <sys/param.h> |
47 |
#include <sys/systm.h> |
49 |
#include <sys/systm.h> |
48 |
#include <sys/kernel.h> |
50 |
#include <sys/kernel.h> |
49 |
#include <sys/module.h> |
51 |
#include <sys/module.h> |
50 |
#include <sys/errno.h> |
52 |
#include <sys/errno.h> |
|
|
53 |
#include <sys/kdb.h> |
51 |
#include <sys/lock.h> |
54 |
#include <sys/lock.h> |
52 |
#include <sys/mutex.h> |
55 |
#include <sys/mutex.h> |
|
|
56 |
#include <sys/proc.h> |
53 |
#include <sys/sx.h> |
57 |
#include <sys/sx.h> |
54 |
#include <sys/syslog.h> |
58 |
#include <sys/syslog.h> |
55 |
#include <sys/bus.h> |
59 |
#include <sys/bus.h> |
Lines 58-63
__FBSDID("$FreeBSD$");
Link Here
|
58 |
#include <machine/bus.h> |
62 |
#include <machine/bus.h> |
59 |
#include <sys/rman.h> |
63 |
#include <sys/rman.h> |
60 |
|
64 |
|
|
|
65 |
#ifdef DEV_ACPI |
66 |
#include <contrib/dev/acpica/include/acpi.h> |
67 |
#include <contrib/dev/acpica/include/accommon.h> |
68 |
#include <dev/acpica/acpivar.h> |
69 |
#endif |
70 |
|
61 |
#include <dev/pci/pcivar.h> |
71 |
#include <dev/pci/pcivar.h> |
62 |
#include <dev/pci/pcireg.h> |
72 |
#include <dev/pci/pcireg.h> |
63 |
#include <dev/iicbus/iicbus.h> |
73 |
#include <dev/iicbus/iicbus.h> |
Lines 70-76
__FBSDID("$FreeBSD$");
Link Here
|
70 |
#define TRANS_PCALL 2 |
80 |
#define TRANS_PCALL 2 |
71 |
#define TRANS_BLOCK 3 |
81 |
#define TRANS_BLOCK 3 |
72 |
|
82 |
|
73 |
static void ig4iic_start(void *xdev); |
83 |
#define DO_POLL(sc) (cold || kdb_active || SCHEDULER_STOPPED() || \ |
|
|
84 |
sc->poll || sc->resume) |
85 |
|
86 |
/* |
87 |
* Clock register values calculation formulas and timings are snarfed from |
88 |
* Linux driver. |
89 |
* *S_SCL_HCNT = IC clock rate * (tHIGH + SDA falling time) - 3 |
90 |
* *S_SCL_LCNT = IC clock rate * (tLOW + SCL falling time) - 1 |
91 |
* SDA_TX_HOLD = IC clock rate * SDA hold time |
92 |
* All results are rounded to nearest. |
93 |
* |
94 |
* tLOW and tHIGH periods of the SCL clock are taken from I2C specification: |
95 |
* Speed mode STD FAST FAST+ HIGH |
96 |
* tHIGH 4.0 ns 0.6 ns 0.26 ns 0.06-0.12 ns |
97 |
* tLOW 4.7 ns 1.3 ns 0.5 ns 0.16-0.32 ns |
98 |
* |
99 |
* HIGH Speed mode tHIGH/tLOW values are depend on bus capacitance. |
100 |
*/ |
101 |
static const struct ig4_cfg ig4iic_configs[] = { |
102 |
[IG4_HASWELL] = { |
103 |
.bus_speed = IG4_CTL_SPEED_FAST, |
104 |
.ss_scl_hcnt = 432, |
105 |
.ss_scl_lcnt = 507, |
106 |
.fs_scl_hcnt = 110, |
107 |
.fs_scl_lcnt = 160, |
108 |
.sda_tx_hold = 9, |
109 |
.txfifo_depth = 32, |
110 |
.rxfifo_depth = 32, |
111 |
}, |
112 |
[IG4_ATOM] = { |
113 |
.bus_speed = IG4_CTL_SPEED_FAST, |
114 |
.ss_scl_hcnt = 512, |
115 |
.ss_scl_lcnt = 512, |
116 |
.fs_scl_hcnt = 85, |
117 |
.fs_scl_lcnt = 153, |
118 |
.sda_tx_hold = 6, |
119 |
.txfifo_depth = 32, |
120 |
.rxfifo_depth = 32, |
121 |
}, |
122 |
[IG4_SKYLAKE] = { |
123 |
/* |
124 |
* IC clock rate: 120 MHz |
125 |
* SDA hold time: 230 ns |
126 |
* SDA falling time: 300 ns |
127 |
* SCL falling time: 300 ns |
128 |
*/ |
129 |
.bus_speed = IG4_CTL_SPEED_FAST, |
130 |
.ss_scl_hcnt = 513, |
131 |
.ss_scl_lcnt = 599, |
132 |
.fs_scl_hcnt = 105, |
133 |
.fs_scl_lcnt = 191, |
134 |
.sda_tx_hold = 28, |
135 |
.txfifo_depth = 64, |
136 |
.rxfifo_depth = 64, |
137 |
}, |
138 |
[IG4_APL] = { |
139 |
/* |
140 |
* IC clock rate: 133 MHz |
141 |
* SDA hold time: 207 ns |
142 |
* SDA falling time: 171 ns |
143 |
* SCL falling time: 208 ns |
144 |
*/ |
145 |
.bus_speed = IG4_CTL_SPEED_FAST, |
146 |
.ss_scl_hcnt = 552, |
147 |
.ss_scl_lcnt = 652, |
148 |
.fs_scl_hcnt = 100, |
149 |
.fs_scl_lcnt = 200, |
150 |
.sda_tx_hold = 28, |
151 |
}, |
152 |
}; |
153 |
|
154 |
static int ig4iic_set_config(ig4iic_softc_t *sc); |
74 |
static void ig4iic_intr(void *cookie); |
155 |
static void ig4iic_intr(void *cookie); |
75 |
static void ig4iic_dump(ig4iic_softc_t *sc); |
156 |
static void ig4iic_dump(ig4iic_softc_t *sc); |
76 |
|
157 |
|
Lines 98-103
reg_read(ig4iic_softc_t *sc, uint32_t reg)
Link Here
|
98 |
return (value); |
179 |
return (value); |
99 |
} |
180 |
} |
100 |
|
181 |
|
|
|
182 |
static void |
183 |
set_intr_mask(ig4iic_softc_t *sc, uint32_t val) |
184 |
{ |
185 |
if (sc->intr_mask != val) { |
186 |
reg_write(sc, IG4_REG_INTR_MASK, val); |
187 |
sc->intr_mask = val; |
188 |
} |
189 |
} |
190 |
|
191 |
static int |
192 |
intrstat2iic(ig4iic_softc_t *sc, uint32_t val) |
193 |
{ |
194 |
uint32_t src; |
195 |
|
196 |
if (val & IG4_INTR_RX_UNDER) |
197 |
reg_read(sc, IG4_REG_CLR_RX_UNDER); |
198 |
if (val & IG4_INTR_RX_OVER) |
199 |
reg_read(sc, IG4_REG_CLR_RX_OVER); |
200 |
if (val & IG4_INTR_TX_OVER) |
201 |
reg_read(sc, IG4_REG_CLR_TX_OVER); |
202 |
|
203 |
if (val & IG4_INTR_TX_ABRT) { |
204 |
src = reg_read(sc, IG4_REG_TX_ABRT_SOURCE); |
205 |
reg_read(sc, IG4_REG_CLR_TX_ABORT); |
206 |
/* User-requested abort. Not really a error */ |
207 |
if (src & IG4_ABRTSRC_TRANSFER) |
208 |
return (IIC_ESTATUS); |
209 |
/* Master has lost arbitration */ |
210 |
if (src & IG4_ABRTSRC_ARBLOST) |
211 |
return (IIC_EBUSBSY); |
212 |
/* Did not receive an acknowledge from the remote slave */ |
213 |
if (src & (IG4_ABRTSRC_TXNOACK_ADDR7 | |
214 |
IG4_ABRTSRC_TXNOACK_ADDR10_1 | |
215 |
IG4_ABRTSRC_TXNOACK_ADDR10_2 | |
216 |
IG4_ABRTSRC_TXNOACK_DATA | |
217 |
IG4_ABRTSRC_GENCALL_NOACK)) |
218 |
return (IIC_ENOACK); |
219 |
/* Programming errors */ |
220 |
if (src & (IG4_ABRTSRC_GENCALL_READ | |
221 |
IG4_ABRTSRC_NORESTART_START | |
222 |
IG4_ABRTSRC_NORESTART_10)) |
223 |
return (IIC_ENOTSUPP); |
224 |
/* Other errors */ |
225 |
if (src & IG4_ABRTSRC_ACKED_START) |
226 |
return (IIC_EBUSERR); |
227 |
} |
228 |
/* |
229 |
* TX_OVER, RX_OVER and RX_UNDER are caused by wrong RX/TX FIFO depth |
230 |
* detection or driver's read/write pipelining errors. |
231 |
*/ |
232 |
if (val & (IG4_INTR_TX_OVER | IG4_INTR_RX_OVER)) |
233 |
return (IIC_EOVERFLOW); |
234 |
if (val & IG4_INTR_RX_UNDER) |
235 |
return (IIC_EUNDERFLOW); |
236 |
|
237 |
return (IIC_NOERR); |
238 |
} |
239 |
|
101 |
/* |
240 |
/* |
102 |
* Enable or disable the controller and wait for the controller to acknowledge |
241 |
* Enable or disable the controller and wait for the controller to acknowledge |
103 |
* the state change. |
242 |
* the state change. |
Lines 113-124
set_controller(ig4iic_softc_t *sc, uint32_t ctl)
Link Here
|
113 |
* When the controller is enabled, interrupt on STOP detect |
252 |
* When the controller is enabled, interrupt on STOP detect |
114 |
* or receive character ready and clear pending interrupts. |
253 |
* or receive character ready and clear pending interrupts. |
115 |
*/ |
254 |
*/ |
116 |
if (ctl & IG4_I2C_ENABLE) { |
255 |
set_intr_mask(sc, 0); |
117 |
reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET | |
256 |
if (ctl & IG4_I2C_ENABLE) |
118 |
IG4_INTR_RX_FULL); |
|
|
119 |
reg_read(sc, IG4_REG_CLR_INTR); |
257 |
reg_read(sc, IG4_REG_CLR_INTR); |
120 |
} else |
|
|
121 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
122 |
|
258 |
|
123 |
reg_write(sc, IG4_REG_I2C_EN, ctl); |
259 |
reg_write(sc, IG4_REG_I2C_EN, ctl); |
124 |
error = IIC_ETIMEOUT; |
260 |
error = IIC_ETIMEOUT; |
Lines 129-147
set_controller(ig4iic_softc_t *sc, uint32_t ctl)
Link Here
|
129 |
error = 0; |
265 |
error = 0; |
130 |
break; |
266 |
break; |
131 |
} |
267 |
} |
132 |
if (cold) |
268 |
pause("i2cslv", 1); |
133 |
DELAY(1000); |
|
|
134 |
else |
135 |
mtx_sleep(sc, &sc->io_lock, 0, "i2cslv", 1); |
136 |
} |
269 |
} |
137 |
return (error); |
270 |
return (error); |
138 |
} |
271 |
} |
139 |
|
272 |
|
140 |
/* |
273 |
/* |
141 |
* Wait up to 25ms for the requested status using a 25uS polling loop. |
274 |
* Wait up to 25ms for the requested interrupt using a 25uS polling loop. |
142 |
*/ |
275 |
*/ |
143 |
static int |
276 |
static int |
144 |
wait_status(ig4iic_softc_t *sc, uint32_t status) |
277 |
wait_intr(ig4iic_softc_t *sc, uint32_t intr) |
145 |
{ |
278 |
{ |
146 |
uint32_t v; |
279 |
uint32_t v; |
147 |
int error; |
280 |
int error; |
Lines 151-175
wait_status(ig4iic_softc_t *sc, uint32_t status)
Link Here
|
151 |
|
284 |
|
152 |
error = IIC_ETIMEOUT; |
285 |
error = IIC_ETIMEOUT; |
153 |
|
286 |
|
154 |
for (;;) { |
287 |
while (error == IIC_ETIMEOUT) { |
155 |
/* |
288 |
/* |
156 |
* Check requested status |
289 |
* Check requested status |
157 |
*/ |
290 |
*/ |
158 |
v = reg_read(sc, IG4_REG_I2C_STA); |
291 |
v = reg_read(sc, IG4_REG_RAW_INTR_STAT); |
159 |
if (v & status) { |
292 |
error = intrstat2iic(sc, v & IG4_INTR_ERR_MASK); |
160 |
error = 0; |
293 |
if (error) |
161 |
break; |
294 |
break; |
162 |
} |
|
|
163 |
|
295 |
|
164 |
/* |
296 |
if (v & intr) { |
165 |
* When waiting for receive data break-out if the interrupt |
297 |
error = 0; |
166 |
* loaded data into the FIFO. |
298 |
break; |
167 |
*/ |
|
|
168 |
if (status & IG4_STATUS_RX_NOTEMPTY) { |
169 |
if (sc->rpos != sc->rnext) { |
170 |
error = 0; |
171 |
break; |
172 |
} |
173 |
} |
299 |
} |
174 |
|
300 |
|
175 |
/* |
301 |
/* |
Lines 177-183
wait_status(ig4iic_softc_t *sc, uint32_t status)
Link Here
|
177 |
* reset the timeout if we see a change in the transmit |
303 |
* reset the timeout if we see a change in the transmit |
178 |
* FIFO level as progress is being made. |
304 |
* FIFO level as progress is being made. |
179 |
*/ |
305 |
*/ |
180 |
if (status & IG4_STATUS_TX_EMPTY) { |
306 |
if (intr & (IG4_INTR_TX_EMPTY | IG4_INTR_STOP_DET)) { |
181 |
v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK; |
307 |
v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK; |
182 |
if (txlvl != v) { |
308 |
if (txlvl != v) { |
183 |
txlvl = v; |
309 |
txlvl = v; |
Lines 188-232
wait_status(ig4iic_softc_t *sc, uint32_t status)
Link Here
|
188 |
/* |
314 |
/* |
189 |
* Stop if we've run out of time. |
315 |
* Stop if we've run out of time. |
190 |
*/ |
316 |
*/ |
191 |
if (count_us >= limit_us) |
317 |
if (count_us >= limit_us) { |
|
|
318 |
error = IIC_ETIMEOUT; |
192 |
break; |
319 |
break; |
|
|
320 |
} |
193 |
|
321 |
|
194 |
/* |
322 |
/* |
195 |
* When waiting for receive data let the interrupt do its |
323 |
* When polling is not requested let the interrupt do its work. |
196 |
* work, otherwise poll with the lock held. |
|
|
197 |
*/ |
324 |
*/ |
198 |
if (status & IG4_STATUS_RX_NOTEMPTY) { |
325 |
if (!DO_POLL(sc)) { |
199 |
mtx_sleep(sc, &sc->io_lock, 0, "i2cwait", |
326 |
mtx_lock(&sc->io_lock); |
|
|
327 |
sc->error = 0; |
328 |
set_intr_mask(sc, intr | IG4_INTR_ERR_MASK); |
329 |
error = mtx_sleep(sc, &sc->io_lock, 0, "i2cwait", |
200 |
(hz + 99) / 100); /* sleep up to 10ms */ |
330 |
(hz + 99) / 100); /* sleep up to 10ms */ |
|
|
331 |
if (error != 0) |
332 |
error = IIC_ETIMEOUT; |
333 |
else |
334 |
error = sc->error; |
335 |
set_intr_mask(sc, 0); |
336 |
mtx_unlock(&sc->io_lock); |
201 |
count_us += 10000; |
337 |
count_us += 10000; |
202 |
} else { |
338 |
} else { |
203 |
DELAY(25); |
339 |
DELAY(25); |
204 |
count_us += 25; |
340 |
count_us += 25; |
|
|
341 |
error = IIC_ETIMEOUT; |
205 |
} |
342 |
} |
206 |
} |
343 |
} |
207 |
|
344 |
|
208 |
return (error); |
345 |
return (error); |
209 |
} |
346 |
} |
210 |
|
347 |
|
211 |
/* |
|
|
212 |
* Read I2C data. The data might have already been read by |
213 |
* the interrupt code, otherwise it is sitting in the data |
214 |
* register. |
215 |
*/ |
216 |
static uint8_t |
217 |
data_read(ig4iic_softc_t *sc) |
218 |
{ |
219 |
uint8_t c; |
220 |
|
221 |
if (sc->rpos == sc->rnext) { |
222 |
c = (uint8_t)reg_read(sc, IG4_REG_DATA_CMD); |
223 |
} else { |
224 |
c = sc->rbuf[sc->rpos & IG4_RBUFMASK]; |
225 |
++sc->rpos; |
226 |
} |
227 |
return (c); |
228 |
} |
229 |
|
230 |
/* |
348 |
/* |
231 |
* Set the slave address. The controller must be disabled when |
349 |
* Set the slave address. The controller must be disabled when |
232 |
* changing the address. |
350 |
* changing the address. |
Lines 250-271
set_slave_addr(ig4iic_softc_t *sc, uint8_t slave)
Link Here
|
250 |
|
368 |
|
251 |
/* |
369 |
/* |
252 |
* Wait for TXFIFO to drain before disabling the controller. |
370 |
* Wait for TXFIFO to drain before disabling the controller. |
253 |
* |
|
|
254 |
* If a write message has not been completed it's really a |
255 |
* programming error, but for now in that case issue an extra |
256 |
* byte + STOP. |
257 |
* |
258 |
* If a read message has not been completed it's also a programming |
259 |
* error, for now just ignore it. |
260 |
*/ |
371 |
*/ |
261 |
wait_status(sc, IG4_STATUS_TX_NOTFULL); |
372 |
wait_intr(sc, IG4_INTR_TX_EMPTY); |
262 |
if (sc->write_started) { |
|
|
263 |
reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_STOP); |
264 |
sc->write_started = 0; |
265 |
} |
266 |
if (sc->read_started) |
267 |
sc->read_started = 0; |
268 |
wait_status(sc, IG4_STATUS_TX_EMPTY); |
269 |
|
373 |
|
270 |
set_controller(sc, 0); |
374 |
set_controller(sc, 0); |
271 |
ctl = reg_read(sc, IG4_REG_CTL); |
375 |
ctl = reg_read(sc, IG4_REG_CTL); |
Lines 288-335
set_slave_addr(ig4iic_softc_t *sc, uint8_t slave)
Link Here
|
288 |
* IICBUS API FUNCTIONS |
392 |
* IICBUS API FUNCTIONS |
289 |
*/ |
393 |
*/ |
290 |
static int |
394 |
static int |
291 |
ig4iic_xfer_start(ig4iic_softc_t *sc, uint16_t slave) |
395 |
ig4iic_xfer_start(ig4iic_softc_t *sc, uint16_t slave, bool repeated_start) |
292 |
{ |
396 |
{ |
293 |
set_slave_addr(sc, slave >> 1); |
397 |
set_slave_addr(sc, slave >> 1); |
|
|
398 |
|
399 |
if (!repeated_start) { |
400 |
/* |
401 |
* Clear any previous TX/RX FIFOs overflow/underflow bits |
402 |
* and I2C bus STOP condition. |
403 |
*/ |
404 |
reg_read(sc, IG4_REG_CLR_INTR); |
405 |
} |
406 |
|
294 |
return (0); |
407 |
return (0); |
295 |
} |
408 |
} |
296 |
|
409 |
|
|
|
410 |
static int |
411 |
ig4iic_xfer_abort(ig4iic_softc_t *sc) |
412 |
{ |
413 |
int error; |
414 |
|
415 |
/* Request send of STOP condition and flush of TX FIFO */ |
416 |
set_controller(sc, IG4_I2C_ABORT | IG4_I2C_ENABLE); |
417 |
/* |
418 |
* Wait for the TX_ABRT interrupt with ABRTSRC_TRANSFER |
419 |
* bit set in TX_ABRT_SOURCE register. |
420 |
*/ |
421 |
error = wait_intr(sc, IG4_INTR_STOP_DET); |
422 |
set_controller(sc, IG4_I2C_ENABLE); |
423 |
|
424 |
return (error == IIC_ESTATUS ? 0 : error); |
425 |
} |
426 |
|
427 |
/* |
428 |
* Amount of unread data before next burst to get better I2C bus utilization. |
429 |
* 2 bytes is enough in FAST mode. 8 bytes is better in FAST+ and HIGH modes. |
430 |
* Intel-recommended value is 16 for DMA transfers with 64-byte depth FIFOs. |
431 |
*/ |
432 |
#define IG4_FIFO_LOWAT 2 |
433 |
|
297 |
static int |
434 |
static int |
298 |
ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len, |
435 |
ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len, |
299 |
bool repeated_start, bool stop) |
436 |
bool repeated_start, bool stop) |
300 |
{ |
437 |
{ |
301 |
uint32_t cmd; |
438 |
uint32_t cmd; |
302 |
uint16_t i; |
439 |
int requested = 0; |
|
|
440 |
int received = 0; |
441 |
int burst, target, lowat = 0; |
303 |
int error; |
442 |
int error; |
304 |
|
443 |
|
305 |
if (len == 0) |
444 |
if (len == 0) |
306 |
return (0); |
445 |
return (0); |
307 |
|
446 |
|
308 |
cmd = IG4_DATA_COMMAND_RD; |
447 |
while (received < len) { |
309 |
cmd |= repeated_start ? IG4_DATA_RESTART : 0; |
448 |
burst = sc->cfg.txfifo_depth - |
310 |
cmd |= stop && len == 1 ? IG4_DATA_STOP : 0; |
449 |
(reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK); |
311 |
|
450 |
if (burst <= 0) { |
312 |
/* Issue request for the first byte (could be last as well). */ |
451 |
error = wait_intr(sc, IG4_INTR_TX_EMPTY); |
313 |
reg_write(sc, IG4_REG_DATA_CMD, cmd); |
452 |
if (error) |
314 |
|
453 |
break; |
315 |
for (i = 0; i < len; i++) { |
454 |
burst = sc->cfg.txfifo_depth; |
316 |
/* |
455 |
} |
317 |
* Maintain a pipeline by queueing the allowance for the next |
456 |
/* Ensure we have enough free space in RXFIFO */ |
318 |
* read before waiting for the current read. |
457 |
burst = MIN(burst, sc->cfg.rxfifo_depth - lowat); |
319 |
*/ |
458 |
target = MIN(requested + burst, (int)len); |
320 |
cmd = IG4_DATA_COMMAND_RD; |
459 |
while (requested < target) { |
321 |
if (i < len - 1) { |
|
|
322 |
cmd = IG4_DATA_COMMAND_RD; |
460 |
cmd = IG4_DATA_COMMAND_RD; |
323 |
cmd |= stop && i == len - 2 ? IG4_DATA_STOP : 0; |
461 |
if (repeated_start && requested == 0) |
|
|
462 |
cmd |= IG4_DATA_RESTART; |
463 |
if (stop && requested == len - 1) |
464 |
cmd |= IG4_DATA_STOP; |
324 |
reg_write(sc, IG4_REG_DATA_CMD, cmd); |
465 |
reg_write(sc, IG4_REG_DATA_CMD, cmd); |
|
|
466 |
requested++; |
467 |
} |
468 |
/* Leave some data queued to maintain the hardware pipeline */ |
469 |
lowat = 0; |
470 |
if (requested != len && requested - received > IG4_FIFO_LOWAT) |
471 |
lowat = IG4_FIFO_LOWAT; |
472 |
/* After TXFLR fills up, clear it by reading available data */ |
473 |
while (received < requested - lowat) { |
474 |
burst = MIN((int)len - received, |
475 |
reg_read(sc, IG4_REG_RXFLR) & IG4_FIFOLVL_MASK); |
476 |
if (burst > 0) { |
477 |
while (burst--) |
478 |
buf[received++] = 0xFF & |
479 |
reg_read(sc, IG4_REG_DATA_CMD); |
480 |
} else { |
481 |
error = wait_intr(sc, IG4_INTR_RX_FULL); |
482 |
if (error) |
483 |
goto out; |
484 |
} |
325 |
} |
485 |
} |
326 |
error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY); |
|
|
327 |
if (error) |
328 |
break; |
329 |
buf[i] = data_read(sc); |
330 |
} |
486 |
} |
331 |
|
487 |
out: |
332 |
(void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE); |
|
|
333 |
return (error); |
488 |
return (error); |
334 |
} |
489 |
} |
335 |
|
490 |
|
Lines 338-361
ig4iic_write(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
Link Here
|
338 |
bool repeated_start, bool stop) |
493 |
bool repeated_start, bool stop) |
339 |
{ |
494 |
{ |
340 |
uint32_t cmd; |
495 |
uint32_t cmd; |
341 |
uint16_t i; |
496 |
int sent = 0; |
|
|
497 |
int burst, target; |
342 |
int error; |
498 |
int error; |
|
|
499 |
bool lowat_set = false; |
343 |
|
500 |
|
344 |
if (len == 0) |
501 |
if (len == 0) |
345 |
return (0); |
502 |
return (0); |
346 |
|
503 |
|
347 |
cmd = repeated_start ? IG4_DATA_RESTART : 0; |
504 |
while (sent < len) { |
348 |
for (i = 0; i < len; i++) { |
505 |
burst = sc->cfg.txfifo_depth - |
349 |
error = wait_status(sc, IG4_STATUS_TX_NOTFULL); |
506 |
(reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK); |
350 |
if (error) |
507 |
target = MIN(sent + burst, (int)len); |
351 |
break; |
508 |
/* Leave some data queued to maintain the hardware pipeline */ |
352 |
cmd |= buf[i]; |
509 |
if (sent == 0 && target != len) { |
353 |
cmd |= stop && i == len - 1 ? IG4_DATA_STOP : 0; |
510 |
lowat_set = true; |
354 |
reg_write(sc, IG4_REG_DATA_CMD, cmd); |
511 |
reg_write(sc, IG4_REG_TX_TL, IG4_FIFO_LOWAT); |
355 |
cmd = 0; |
512 |
} |
|
|
513 |
while(sent < target) { |
514 |
cmd = buf[sent]; |
515 |
if (repeated_start && sent == 0) |
516 |
cmd |= IG4_DATA_RESTART; |
517 |
if (stop && sent == len - 1) |
518 |
cmd |= IG4_DATA_STOP; |
519 |
reg_write(sc, IG4_REG_DATA_CMD, cmd); |
520 |
sent++; |
521 |
} |
522 |
if (sent < len) { |
523 |
error = wait_intr(sc, IG4_INTR_TX_EMPTY); |
524 |
if (error) |
525 |
break; |
526 |
} |
356 |
} |
527 |
} |
|
|
528 |
if (lowat_set) |
529 |
reg_write(sc, IG4_REG_TX_TL, 0); |
357 |
|
530 |
|
358 |
(void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE); |
|
|
359 |
return (error); |
531 |
return (error); |
360 |
} |
532 |
} |
361 |
|
533 |
|
Lines 369-374
ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
Link Here
|
369 |
int unit; |
541 |
int unit; |
370 |
bool rpstart; |
542 |
bool rpstart; |
371 |
bool stop; |
543 |
bool stop; |
|
|
544 |
bool allocated; |
372 |
|
545 |
|
373 |
/* |
546 |
/* |
374 |
* The hardware interface imposes limits on allowed I2C messages. |
547 |
* The hardware interface imposes limits on allowed I2C messages. |
Lines 429-436
ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
Link Here
|
429 |
return (IIC_ENOTSUPP); |
602 |
return (IIC_ENOTSUPP); |
430 |
} |
603 |
} |
431 |
|
604 |
|
432 |
sx_xlock(&sc->call_lock); |
605 |
/* Check if device is already allocated with iicbus_request_bus() */ |
433 |
mtx_lock(&sc->io_lock); |
606 |
allocated = sx_xlocked(&sc->call_lock) != 0; |
|
|
607 |
if (!allocated) |
608 |
sx_xlock(&sc->call_lock); |
434 |
|
609 |
|
435 |
/* Debugging - dump registers. */ |
610 |
/* Debugging - dump registers. */ |
436 |
if (ig4_dump) { |
611 |
if (ig4_dump) { |
Lines 447-467
ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
Link Here
|
447 |
*/ |
622 |
*/ |
448 |
reg_read(sc, IG4_REG_CLR_TX_ABORT); |
623 |
reg_read(sc, IG4_REG_CLR_TX_ABORT); |
449 |
|
624 |
|
450 |
/* |
|
|
451 |
* Clean out any previously received data. |
452 |
*/ |
453 |
if (sc->rpos != sc->rnext && bootverbose) { |
454 |
device_printf(sc->dev, "discarding %d bytes of spurious data\n", |
455 |
sc->rnext - sc->rpos); |
456 |
} |
457 |
sc->rpos = 0; |
458 |
sc->rnext = 0; |
459 |
|
460 |
rpstart = false; |
625 |
rpstart = false; |
461 |
error = 0; |
626 |
error = 0; |
462 |
for (i = 0; i < nmsgs; i++) { |
627 |
for (i = 0; i < nmsgs; i++) { |
463 |
if ((msgs[i].flags & IIC_M_NOSTART) == 0) { |
628 |
if ((msgs[i].flags & IIC_M_NOSTART) == 0) { |
464 |
error = ig4iic_xfer_start(sc, msgs[i].slave); |
629 |
error = ig4iic_xfer_start(sc, msgs[i].slave, rpstart); |
465 |
} else { |
630 |
} else { |
466 |
if (!sc->slave_valid || |
631 |
if (!sc->slave_valid || |
467 |
(msgs[i].slave >> 1) != sc->last_slave) { |
632 |
(msgs[i].slave >> 1) != sc->last_slave) { |
Lines 482-495
ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
Link Here
|
482 |
else |
647 |
else |
483 |
error = ig4iic_write(sc, msgs[i].buf, msgs[i].len, |
648 |
error = ig4iic_write(sc, msgs[i].buf, msgs[i].len, |
484 |
rpstart, stop); |
649 |
rpstart, stop); |
485 |
if (error != 0) |
650 |
|
|
|
651 |
/* Wait for error or stop condition occurred on the I2C bus */ |
652 |
if (stop && error == 0) { |
653 |
error = wait_intr(sc, IG4_INTR_STOP_DET); |
654 |
if (error == 0) |
655 |
reg_read(sc, IG4_REG_CLR_INTR); |
656 |
} |
657 |
|
658 |
if (error != 0) { |
659 |
/* |
660 |
* Send STOP condition if it's not done yet and flush |
661 |
* both FIFOs. Do a controller soft reset if transfer |
662 |
* abort is failed. |
663 |
*/ |
664 |
if (((reg_read(sc, IG4_REG_RAW_INTR_STAT) & |
665 |
(IG4_INTR_START_DET | IG4_INTR_STOP_DET)) |
666 |
== IG4_INTR_START_DET) && |
667 |
ig4iic_xfer_abort(sc) != 0) { |
668 |
device_printf(sc->dev, "Failed to abort " |
669 |
"transfer. Do the controller reset.\n"); |
670 |
ig4iic_set_config(sc); |
671 |
} else { |
672 |
while (reg_read(sc, IG4_REG_I2C_STA) & |
673 |
IG4_STATUS_RX_NOTEMPTY) |
674 |
reg_read(sc, IG4_REG_DATA_CMD); |
675 |
reg_read(sc, IG4_REG_TX_ABRT_SOURCE); |
676 |
reg_read(sc, IG4_REG_CLR_INTR); |
677 |
} |
486 |
break; |
678 |
break; |
|
|
679 |
} |
487 |
|
680 |
|
488 |
rpstart = !stop; |
681 |
rpstart = !stop; |
489 |
} |
682 |
} |
490 |
|
683 |
|
491 |
mtx_unlock(&sc->io_lock); |
684 |
if (!allocated) |
492 |
sx_unlock(&sc->call_lock); |
685 |
sx_unlock(&sc->call_lock); |
493 |
return (error); |
686 |
return (error); |
494 |
} |
687 |
} |
495 |
|
688 |
|
Lines 497-505
int
Link Here
|
497 |
ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) |
690 |
ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) |
498 |
{ |
691 |
{ |
499 |
ig4iic_softc_t *sc = device_get_softc(dev); |
692 |
ig4iic_softc_t *sc = device_get_softc(dev); |
|
|
693 |
bool allocated; |
500 |
|
694 |
|
501 |
sx_xlock(&sc->call_lock); |
695 |
allocated = sx_xlocked(&sc->call_lock) != 0; |
502 |
mtx_lock(&sc->io_lock); |
696 |
if (!allocated) |
|
|
697 |
sx_xlock(&sc->call_lock); |
503 |
|
698 |
|
504 |
/* TODO handle speed configuration? */ |
699 |
/* TODO handle speed configuration? */ |
505 |
if (oldaddr != NULL) |
700 |
if (oldaddr != NULL) |
Lines 508-539
ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
Link Here
|
508 |
if (addr == IIC_UNKNOWN) |
703 |
if (addr == IIC_UNKNOWN) |
509 |
sc->slave_valid = false; |
704 |
sc->slave_valid = false; |
510 |
|
705 |
|
511 |
mtx_unlock(&sc->io_lock); |
706 |
if (!allocated) |
512 |
sx_unlock(&sc->call_lock); |
707 |
sx_unlock(&sc->call_lock); |
513 |
return (0); |
708 |
return (0); |
514 |
} |
709 |
} |
515 |
|
710 |
|
516 |
/* |
|
|
517 |
* Called from ig4iic_pci_attach/detach() |
518 |
*/ |
519 |
int |
711 |
int |
520 |
ig4iic_attach(ig4iic_softc_t *sc) |
712 |
ig4iic_callback(device_t dev, int index, caddr_t data) |
|
|
713 |
{ |
714 |
ig4iic_softc_t *sc = device_get_softc(dev); |
715 |
int error = 0; |
716 |
int how; |
717 |
|
718 |
/* |
719 |
* Unfortunately, iicbus_request_bus() can return error code in both |
720 |
* formats, POSIX and IIC. Here we use EAGAIN instead of IIC_EBUSBSY |
721 |
* to match other possibly buggy iicbus_callback implementations. |
722 |
* As iicbus_poll() returns IIC_EBUSBSY, caller should check returned |
723 |
* value for both EAGAIN and IIC_EBUSBSY. Other error codes are POSIX. |
724 |
*/ |
725 |
switch (index) { |
726 |
case IIC_REQUEST_BUS: |
727 |
/* force polling if ig4iic is requested with IIC_DONTWAIT */ |
728 |
how = *(int *)data; |
729 |
if ((how & IIC_WAIT) == 0) { |
730 |
if (sx_try_xlock(&sc->call_lock) == 0) |
731 |
error = EWOULDBLOCK; |
732 |
else |
733 |
sc->poll = true; |
734 |
} else |
735 |
sx_xlock(&sc->call_lock); |
736 |
break; |
737 |
|
738 |
case IIC_RELEASE_BUS: |
739 |
sc->poll = false; |
740 |
sx_unlock(&sc->call_lock); |
741 |
break; |
742 |
|
743 |
default: |
744 |
error = EINVAL; |
745 |
} |
746 |
|
747 |
return (error); |
748 |
} |
749 |
|
750 |
#ifdef DEV_ACPI |
751 |
static int |
752 |
ig4iic_acpi_params(ig4iic_softc_t *sc, char *method, |
753 |
uint16_t *scl_hcnt, uint16_t *scl_lcnt, uint16_t *sda_tx_hold) |
521 |
{ |
754 |
{ |
|
|
755 |
ACPI_BUFFER buf; |
756 |
ACPI_HANDLE handle; |
757 |
ACPI_OBJECT *obj, *elems; |
522 |
int error; |
758 |
int error; |
|
|
759 |
|
760 |
handle = acpi_get_handle(sc->dev); |
761 |
if (handle == NULL) |
762 |
return (ENXIO); |
763 |
|
764 |
buf.Pointer = NULL; |
765 |
buf.Length = ACPI_ALLOCATE_BUFFER; |
766 |
|
767 |
if (ACPI_FAILURE(AcpiEvaluateObject(handle, method, NULL, &buf))) |
768 |
return (ENXIO); |
769 |
|
770 |
error = ENXIO; |
771 |
obj = (ACPI_OBJECT *)buf.Pointer; |
772 |
if (obj->Type == ACPI_TYPE_PACKAGE && obj->Package.Count == 3) { |
773 |
elems = obj->Package.Elements; |
774 |
*scl_hcnt = elems[0].Integer.Value & IG4_SCL_CLOCK_MASK; |
775 |
*scl_lcnt = elems[1].Integer.Value & IG4_SCL_CLOCK_MASK; |
776 |
*sda_tx_hold = elems[2].Integer.Value & IG4_SDA_TX_HOLD_MASK; |
777 |
error = 0; |
778 |
} |
779 |
|
780 |
AcpiOsFree(obj); |
781 |
|
782 |
return (error); |
783 |
} |
784 |
#endif /* DEV_ACPI */ |
785 |
|
786 |
static void |
787 |
ig4iic_get_config(ig4iic_softc_t *sc) |
788 |
{ |
789 |
const struct ig4_cfg *cfg; |
523 |
uint32_t v; |
790 |
uint32_t v; |
|
|
791 |
#ifdef DEV_ACPI |
792 |
uint16_t sda_tx_hold; |
793 |
#endif |
524 |
|
794 |
|
525 |
mtx_init(&sc->io_lock, "IG4 I/O lock", NULL, MTX_DEF); |
795 |
/* Fetch default hardware config from controller */ |
526 |
sx_init(&sc->call_lock, "IG4 call lock"); |
796 |
sc->cfg.version = reg_read(sc, IG4_REG_COMP_VER); |
|
|
797 |
sc->cfg.bus_speed = reg_read(sc, IG4_REG_CTL) & IG4_CTL_SPEED_MASK; |
798 |
sc->cfg.ss_scl_hcnt = |
799 |
reg_read(sc, IG4_REG_SS_SCL_HCNT) & IG4_SCL_CLOCK_MASK; |
800 |
sc->cfg.ss_scl_lcnt = |
801 |
reg_read(sc, IG4_REG_SS_SCL_LCNT) & IG4_SCL_CLOCK_MASK; |
802 |
sc->cfg.fs_scl_hcnt = |
803 |
reg_read(sc, IG4_REG_FS_SCL_HCNT) & IG4_SCL_CLOCK_MASK; |
804 |
sc->cfg.fs_scl_lcnt = |
805 |
reg_read(sc, IG4_REG_FS_SCL_LCNT) & IG4_SCL_CLOCK_MASK; |
806 |
sc->cfg.sda_tx_hold = |
807 |
reg_read(sc, IG4_REG_SDA_HOLD) & IG4_SDA_TX_HOLD_MASK; |
808 |
|
809 |
if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { |
810 |
/* REG_COMP_PARAM1 register is not documented in Intel specs */ |
811 |
v = reg_read(sc, IG4_REG_COMP_PARAM1); |
812 |
if (IG4_PARAM1_TXFIFO_DEPTH(v) != 0) |
813 |
sc->cfg.txfifo_depth = IG4_PARAM1_TXFIFO_DEPTH(v); |
814 |
if (IG4_PARAM1_RXFIFO_DEPTH(v) != 0) |
815 |
sc->cfg.rxfifo_depth = IG4_PARAM1_RXFIFO_DEPTH(v); |
816 |
} else { |
817 |
/* |
818 |
* Hardware does not allow FIFO Threshold Levels value to be |
819 |
* set larger than the depth of the buffer. If an attempt is |
820 |
* made to do that, the actual value set will be the maximum |
821 |
* depth of the buffer. |
822 |
*/ |
823 |
v = reg_read(sc, IG4_REG_TX_TL); |
824 |
reg_write(sc, IG4_REG_TX_TL, v | IG4_FIFO_MASK); |
825 |
sc->cfg.txfifo_depth = |
826 |
(reg_read(sc, IG4_REG_TX_TL) & IG4_FIFO_MASK) + 1; |
827 |
reg_write(sc, IG4_REG_TX_TL, v); |
828 |
v = reg_read(sc, IG4_REG_RX_TL); |
829 |
reg_write(sc, IG4_REG_RX_TL, v | IG4_FIFO_MASK); |
830 |
sc->cfg.rxfifo_depth = |
831 |
(reg_read(sc, IG4_REG_RX_TL) & IG4_FIFO_MASK) + 1; |
832 |
reg_write(sc, IG4_REG_RX_TL, v); |
833 |
} |
834 |
|
835 |
/* Override hardware config with precalculated counter values */ |
836 |
if (sc->version < nitems(ig4iic_configs)) { |
837 |
cfg = &ig4iic_configs[sc->version]; |
838 |
if (cfg->bus_speed != 0) |
839 |
sc->cfg.bus_speed = cfg->bus_speed; |
840 |
if (cfg->ss_scl_hcnt != 0) |
841 |
sc->cfg.ss_scl_hcnt = cfg->ss_scl_hcnt; |
842 |
if (cfg->ss_scl_lcnt != 0) |
843 |
sc->cfg.ss_scl_lcnt = cfg->ss_scl_lcnt; |
844 |
if (cfg->fs_scl_hcnt != 0) |
845 |
sc->cfg.fs_scl_hcnt = cfg->fs_scl_hcnt; |
846 |
if (cfg->fs_scl_lcnt != 0) |
847 |
sc->cfg.fs_scl_lcnt = cfg->fs_scl_lcnt; |
848 |
if (cfg->sda_tx_hold != 0) |
849 |
sc->cfg.sda_tx_hold = cfg->sda_tx_hold; |
850 |
if (cfg->txfifo_depth != 0) |
851 |
sc->cfg.txfifo_depth = cfg->txfifo_depth; |
852 |
if (cfg->rxfifo_depth != 0) |
853 |
sc->cfg.rxfifo_depth = cfg->rxfifo_depth; |
854 |
} |
855 |
|
856 |
if (sc->cfg.bus_speed != IG4_CTL_SPEED_STD) |
857 |
sc->cfg.bus_speed = IG4_CTL_SPEED_FAST; |
858 |
|
859 |
#ifdef DEV_ACPI |
860 |
/* Evaluate SSCN and FMCN ACPI methods to fetch timings */ |
861 |
if (ig4iic_acpi_params(sc, "SSCN", |
862 |
&sc->cfg.ss_scl_hcnt, &sc->cfg.ss_scl_lcnt, &sda_tx_hold) == 0 && |
863 |
sc->cfg.bus_speed == IG4_CTL_SPEED_STD && |
864 |
sda_tx_hold != 0) |
865 |
sc->cfg.sda_tx_hold = sda_tx_hold; |
866 |
if (ig4iic_acpi_params(sc, "FMCN", |
867 |
&sc->cfg.fs_scl_hcnt, &sc->cfg.fs_scl_lcnt, &sda_tx_hold) == 0 && |
868 |
sc->cfg.bus_speed == IG4_CTL_SPEED_FAST && |
869 |
sda_tx_hold != 0) |
870 |
sc->cfg.sda_tx_hold = sda_tx_hold; |
871 |
#endif |
872 |
} |
873 |
|
874 |
static int |
875 |
ig4iic_set_config(ig4iic_softc_t *sc) |
876 |
{ |
877 |
uint32_t v; |
527 |
|
878 |
|
528 |
v = reg_read(sc, IG4_REG_DEVIDLE_CTRL); |
879 |
v = reg_read(sc, IG4_REG_DEVIDLE_CTRL); |
529 |
if (sc->version == IG4_SKYLAKE && (v & IG4_RESTORE_REQUIRED) ) { |
880 |
if (sc->version == IG4_SKYLAKE && (v & IG4_RESTORE_REQUIRED) ) { |
530 |
reg_write(sc, IG4_REG_DEVIDLE_CTRL, IG4_DEVICE_IDLE | IG4_RESTORE_REQUIRED); |
881 |
reg_write(sc, IG4_REG_DEVIDLE_CTRL, IG4_DEVICE_IDLE | IG4_RESTORE_REQUIRED); |
531 |
reg_write(sc, IG4_REG_DEVIDLE_CTRL, 0); |
882 |
reg_write(sc, IG4_REG_DEVIDLE_CTRL, 0); |
|
|
883 |
} |
532 |
|
884 |
|
|
|
885 |
if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { |
886 |
reg_write(sc, IG4_REG_RESETS_HSW, IG4_RESETS_ASSERT_HSW); |
887 |
reg_write(sc, IG4_REG_RESETS_HSW, IG4_RESETS_DEASSERT_HSW); |
888 |
} else if (sc->version == IG4_SKYLAKE) { |
533 |
reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_ASSERT_SKL); |
889 |
reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_ASSERT_SKL); |
534 |
reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_DEASSERT_SKL); |
890 |
reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_DEASSERT_SKL); |
535 |
DELAY(1000); |
|
|
536 |
} |
891 |
} |
|
|
892 |
pause("i2crst", 1); |
537 |
|
893 |
|
538 |
if (sc->version == IG4_ATOM) |
894 |
if (sc->version == IG4_ATOM) |
539 |
v = reg_read(sc, IG4_REG_COMP_TYPE); |
895 |
v = reg_read(sc, IG4_REG_COMP_TYPE); |
Lines 563-597
ig4iic_attach(ig4iic_softc_t *sc)
Link Here
|
563 |
|
919 |
|
564 |
if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { |
920 |
if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { |
565 |
v = reg_read(sc, IG4_REG_COMP_VER); |
921 |
v = reg_read(sc, IG4_REG_COMP_VER); |
566 |
if (v < IG4_COMP_MIN_VER) { |
922 |
if (v < IG4_COMP_MIN_VER) |
567 |
error = ENXIO; |
923 |
return(ENXIO); |
568 |
goto done; |
|
|
569 |
} |
570 |
} |
924 |
} |
571 |
v = reg_read(sc, IG4_REG_SS_SCL_HCNT); |
|
|
572 |
v = reg_read(sc, IG4_REG_SS_SCL_LCNT); |
573 |
v = reg_read(sc, IG4_REG_FS_SCL_HCNT); |
574 |
v = reg_read(sc, IG4_REG_FS_SCL_LCNT); |
575 |
v = reg_read(sc, IG4_REG_SDA_HOLD); |
576 |
|
925 |
|
577 |
v = reg_read(sc, IG4_REG_SS_SCL_HCNT); |
926 |
if (set_controller(sc, 0)) { |
578 |
reg_write(sc, IG4_REG_FS_SCL_HCNT, v); |
927 |
device_printf(sc->dev, "controller error during attach-1\n"); |
579 |
v = reg_read(sc, IG4_REG_SS_SCL_LCNT); |
928 |
return (ENXIO); |
580 |
reg_write(sc, IG4_REG_FS_SCL_LCNT, v); |
929 |
} |
581 |
|
930 |
|
582 |
/* |
931 |
reg_read(sc, IG4_REG_CLR_INTR); |
583 |
* Program based on a 25000 Hz clock. This is a bit of a |
932 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
584 |
* hack (obviously). The defaults are 400 and 470 for standard |
933 |
sc->intr_mask = 0; |
585 |
* and 60 and 130 for fast. The defaults for standard fail |
934 |
|
586 |
* utterly (presumably cause an abort) because the clock time |
935 |
reg_write(sc, IG4_REG_SS_SCL_HCNT, sc->cfg.ss_scl_hcnt); |
587 |
* is ~18.8ms by default. This brings it down to ~4ms (for now). |
936 |
reg_write(sc, IG4_REG_SS_SCL_LCNT, sc->cfg.ss_scl_lcnt); |
588 |
*/ |
937 |
reg_write(sc, IG4_REG_FS_SCL_HCNT, sc->cfg.fs_scl_hcnt); |
589 |
reg_write(sc, IG4_REG_SS_SCL_HCNT, 100); |
938 |
reg_write(sc, IG4_REG_FS_SCL_LCNT, sc->cfg.fs_scl_lcnt); |
590 |
reg_write(sc, IG4_REG_SS_SCL_LCNT, 125); |
939 |
reg_write(sc, IG4_REG_SDA_HOLD, sc->cfg.sda_tx_hold); |
591 |
reg_write(sc, IG4_REG_FS_SCL_HCNT, 100); |
|
|
592 |
reg_write(sc, IG4_REG_FS_SCL_LCNT, 125); |
593 |
if (sc->version == IG4_SKYLAKE) |
594 |
reg_write(sc, IG4_REG_SDA_HOLD, 28); |
595 |
|
940 |
|
596 |
/* |
941 |
/* |
597 |
* Use a threshold of 1 so we get interrupted on each character, |
942 |
* Use a threshold of 1 so we get interrupted on each character, |
Lines 600-612
ig4iic_attach(ig4iic_softc_t *sc)
Link Here
|
600 |
* |
945 |
* |
601 |
* See ig4_var.h for details on interrupt handler synchronization. |
946 |
* See ig4_var.h for details on interrupt handler synchronization. |
602 |
*/ |
947 |
*/ |
603 |
reg_write(sc, IG4_REG_RX_TL, 1); |
948 |
reg_write(sc, IG4_REG_RX_TL, 0); |
|
|
949 |
reg_write(sc, IG4_REG_TX_TL, 0); |
604 |
|
950 |
|
605 |
reg_write(sc, IG4_REG_CTL, |
951 |
reg_write(sc, IG4_REG_CTL, |
606 |
IG4_CTL_MASTER | |
952 |
IG4_CTL_MASTER | |
607 |
IG4_CTL_SLAVE_DISABLE | |
953 |
IG4_CTL_SLAVE_DISABLE | |
608 |
IG4_CTL_RESTARTEN | |
954 |
IG4_CTL_RESTARTEN | |
609 |
IG4_CTL_SPEED_STD); |
955 |
(sc->cfg.bus_speed & IG4_CTL_SPEED_MASK)); |
|
|
956 |
|
957 |
/* Force setting of the target address on the next transfer */ |
958 |
sc->slave_valid = 0; |
959 |
|
960 |
return (0); |
961 |
} |
962 |
|
963 |
/* |
964 |
* Called from ig4iic_pci_attach/detach() |
965 |
*/ |
966 |
int |
967 |
ig4iic_attach(ig4iic_softc_t *sc) |
968 |
{ |
969 |
int error; |
970 |
|
971 |
mtx_init(&sc->io_lock, "IG4 I/O lock", NULL, MTX_DEF); |
972 |
sx_init(&sc->call_lock, "IG4 call lock"); |
973 |
|
974 |
ig4iic_get_config(sc); |
975 |
|
976 |
error = ig4iic_set_config(sc); |
977 |
if (error) |
978 |
goto done; |
610 |
|
979 |
|
611 |
sc->iicbus = device_add_child(sc->dev, "iicbus", -1); |
980 |
sc->iicbus = device_add_child(sc->dev, "iicbus", -1); |
612 |
if (sc->iicbus == NULL) { |
981 |
if (sc->iicbus == NULL) { |
Lines 615-639
ig4iic_attach(ig4iic_softc_t *sc)
Link Here
|
615 |
goto done; |
984 |
goto done; |
616 |
} |
985 |
} |
617 |
|
986 |
|
618 |
#if 0 |
987 |
if (set_controller(sc, IG4_I2C_ENABLE)) { |
619 |
/* |
|
|
620 |
* Don't do this, it blows up the PCI config |
621 |
*/ |
622 |
if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { |
623 |
reg_write(sc, IG4_REG_RESETS_HSW, IG4_RESETS_ASSERT_HSW); |
624 |
reg_write(sc, IG4_REG_RESETS_HSW, IG4_RESETS_DEASSERT_HSW); |
625 |
} else if (sc->version = IG4_SKYLAKE) { |
626 |
reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_ASSERT_SKL); |
627 |
reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_DEASSERT_SKL); |
628 |
} |
629 |
#endif |
630 |
|
631 |
mtx_lock(&sc->io_lock); |
632 |
if (set_controller(sc, 0)) |
633 |
device_printf(sc->dev, "controller error during attach-1\n"); |
634 |
if (set_controller(sc, IG4_I2C_ENABLE)) |
635 |
device_printf(sc->dev, "controller error during attach-2\n"); |
988 |
device_printf(sc->dev, "controller error during attach-2\n"); |
636 |
mtx_unlock(&sc->io_lock); |
989 |
error = ENXIO; |
|
|
990 |
goto done; |
991 |
} |
992 |
if (set_controller(sc, 0)) { |
993 |
device_printf(sc->dev, "controller error during attach-3\n"); |
994 |
error = ENXIO; |
995 |
goto done; |
996 |
} |
637 |
error = bus_setup_intr(sc->dev, sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE, |
997 |
error = bus_setup_intr(sc->dev, sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE, |
638 |
NULL, ig4iic_intr, sc, &sc->intr_handle); |
998 |
NULL, ig4iic_intr, sc, &sc->intr_handle); |
639 |
if (error) { |
999 |
if (error) { |
Lines 641-678
ig4iic_attach(ig4iic_softc_t *sc)
Link Here
|
641 |
"Unable to setup irq: error %d\n", error); |
1001 |
"Unable to setup irq: error %d\n", error); |
642 |
} |
1002 |
} |
643 |
|
1003 |
|
644 |
sc->enum_hook.ich_func = ig4iic_start; |
|
|
645 |
sc->enum_hook.ich_arg = sc->dev; |
646 |
|
647 |
/* |
648 |
* We have to wait until interrupts are enabled. I2C read and write |
649 |
* only works if the interrupts are available. |
650 |
*/ |
651 |
if (config_intrhook_establish(&sc->enum_hook) != 0) |
652 |
error = ENOMEM; |
653 |
else |
654 |
error = 0; |
655 |
|
656 |
done: |
657 |
return (error); |
658 |
} |
659 |
|
660 |
void |
661 |
ig4iic_start(void *xdev) |
662 |
{ |
663 |
int error; |
664 |
ig4iic_softc_t *sc; |
665 |
device_t dev = (device_t)xdev; |
666 |
|
667 |
sc = device_get_softc(dev); |
668 |
|
669 |
config_intrhook_disestablish(&sc->enum_hook); |
670 |
|
671 |
error = bus_generic_attach(sc->dev); |
1004 |
error = bus_generic_attach(sc->dev); |
672 |
if (error) { |
1005 |
if (error) { |
673 |
device_printf(sc->dev, |
1006 |
device_printf(sc->dev, |
674 |
"failed to attach child: error %d\n", error); |
1007 |
"failed to attach child: error %d\n", error); |
675 |
} |
1008 |
} |
|
|
1009 |
|
1010 |
done: |
1011 |
return (error); |
676 |
} |
1012 |
} |
677 |
|
1013 |
|
678 |
int |
1014 |
int |
Lines 691-704
ig4iic_detach(ig4iic_softc_t *sc)
Link Here
|
691 |
bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); |
1027 |
bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); |
692 |
|
1028 |
|
693 |
sx_xlock(&sc->call_lock); |
1029 |
sx_xlock(&sc->call_lock); |
694 |
mtx_lock(&sc->io_lock); |
|
|
695 |
|
1030 |
|
696 |
sc->iicbus = NULL; |
1031 |
sc->iicbus = NULL; |
697 |
sc->intr_handle = NULL; |
1032 |
sc->intr_handle = NULL; |
698 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
1033 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
699 |
set_controller(sc, 0); |
1034 |
set_controller(sc, 0); |
700 |
|
1035 |
|
701 |
mtx_unlock(&sc->io_lock); |
|
|
702 |
sx_xunlock(&sc->call_lock); |
1036 |
sx_xunlock(&sc->call_lock); |
703 |
|
1037 |
|
704 |
mtx_destroy(&sc->io_lock); |
1038 |
mtx_destroy(&sc->io_lock); |
Lines 707-712
ig4iic_detach(ig4iic_softc_t *sc)
Link Here
|
707 |
return (0); |
1041 |
return (0); |
708 |
} |
1042 |
} |
709 |
|
1043 |
|
|
|
1044 |
int |
1045 |
ig4iic_suspend(ig4iic_softc_t *sc) |
1046 |
{ |
1047 |
int error; |
1048 |
|
1049 |
/* suspend all children */ |
1050 |
error = bus_generic_suspend(sc->dev); |
1051 |
|
1052 |
/* |
1053 |
* set IG4_DEVICE_IDLE and IG4_RESTORE_REQUIRED |
1054 |
* to place the device in the idle state, just to be safe |
1055 |
*/ |
1056 |
if (sc->version == IG4_SKYLAKE) { |
1057 |
sx_xlock(&sc->call_lock); |
1058 |
|
1059 |
reg_write(sc, IG4_REG_DEVIDLE_CTRL, |
1060 |
IG4_DEVICE_IDLE | IG4_RESTORE_REQUIRED); |
1061 |
|
1062 |
sx_xunlock(&sc->call_lock); |
1063 |
} |
1064 |
|
1065 |
return (error); |
1066 |
} |
1067 |
|
1068 |
int ig4iic_resume(ig4iic_softc_t *sc) |
1069 |
{ |
1070 |
int error; |
1071 |
|
1072 |
sx_xlock(&sc->call_lock); |
1073 |
/* Use polling as interrupts might not be available at this moment */ |
1074 |
sc->resume = true; |
1075 |
if (ig4iic_set_config(sc)) |
1076 |
device_printf(sc->dev, "controller error during resume\n"); |
1077 |
sx_xunlock(&sc->call_lock); |
1078 |
|
1079 |
error = bus_generic_resume(sc->dev); |
1080 |
|
1081 |
sx_xlock(&sc->call_lock); |
1082 |
sc->resume = false; |
1083 |
sx_xunlock(&sc->call_lock); |
1084 |
|
1085 |
return (error); |
1086 |
} |
1087 |
|
710 |
/* |
1088 |
/* |
711 |
* Interrupt Operation, see ig4_var.h for locking semantics. |
1089 |
* Interrupt Operation, see ig4_var.h for locking semantics. |
712 |
*/ |
1090 |
*/ |
Lines 717-745
ig4iic_intr(void *cookie)
Link Here
|
717 |
uint32_t status; |
1095 |
uint32_t status; |
718 |
|
1096 |
|
719 |
mtx_lock(&sc->io_lock); |
1097 |
mtx_lock(&sc->io_lock); |
720 |
/* reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/ |
1098 |
if (sc->intr_mask != 0) { |
721 |
reg_read(sc, IG4_REG_CLR_INTR); |
1099 |
status = reg_read(sc, IG4_REG_INTR_STAT); |
722 |
status = reg_read(sc, IG4_REG_I2C_STA); |
1100 |
set_intr_mask(sc, 0); |
723 |
while (status & IG4_STATUS_RX_NOTEMPTY) { |
1101 |
sc->error = intrstat2iic(sc, status); |
724 |
sc->rbuf[sc->rnext & IG4_RBUFMASK] = |
1102 |
wakeup(sc); |
725 |
(uint8_t)reg_read(sc, IG4_REG_DATA_CMD); |
1103 |
} else |
726 |
++sc->rnext; |
1104 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
727 |
status = reg_read(sc, IG4_REG_I2C_STA); |
|
|
728 |
} |
729 |
|
730 |
/* |
731 |
* Workaround to trigger pending interrupt if IG4_REG_INTR_STAT |
732 |
* is changed after clearing it |
733 |
*/ |
734 |
if (sc->access_intr_mask != 0) { |
735 |
status = reg_read(sc, IG4_REG_INTR_MASK); |
736 |
if (status != 0) { |
737 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
738 |
reg_write(sc, IG4_REG_INTR_MASK, status); |
739 |
} |
740 |
} |
741 |
|
742 |
wakeup(sc); |
743 |
mtx_unlock(&sc->io_lock); |
1105 |
mtx_unlock(&sc->io_lock); |
744 |
} |
1106 |
} |
745 |
|
1107 |
|
Lines 773-782
ig4iic_dump(ig4iic_softc_t *sc)
Link Here
|
773 |
REGDUMP(sc, IG4_REG_DMA_RDLR); |
1135 |
REGDUMP(sc, IG4_REG_DMA_RDLR); |
774 |
REGDUMP(sc, IG4_REG_SDA_SETUP); |
1136 |
REGDUMP(sc, IG4_REG_SDA_SETUP); |
775 |
REGDUMP(sc, IG4_REG_ENABLE_STATUS); |
1137 |
REGDUMP(sc, IG4_REG_ENABLE_STATUS); |
776 |
if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { |
1138 |
REGDUMP(sc, IG4_REG_COMP_PARAM1); |
777 |
REGDUMP(sc, IG4_REG_COMP_PARAM1); |
1139 |
REGDUMP(sc, IG4_REG_COMP_VER); |
778 |
REGDUMP(sc, IG4_REG_COMP_VER); |
|
|
779 |
} |
780 |
if (sc->version == IG4_ATOM) { |
1140 |
if (sc->version == IG4_ATOM) { |
781 |
REGDUMP(sc, IG4_REG_COMP_TYPE); |
1141 |
REGDUMP(sc, IG4_REG_COMP_TYPE); |
782 |
REGDUMP(sc, IG4_REG_CLK_PARMS); |
1142 |
REGDUMP(sc, IG4_REG_CLK_PARMS); |