spi.c (b109946d7564afde6f3d3b3a78f428c8da14e17c) spi.c (5adcec04b5abd4971f1678d6ee1369cc9ecaa90d)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2016 Oleksandr Tymoshenko <gonzo@FreeBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 16 unchanged lines hidden (view full) ---

25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include "opt_acpi.h"
30
31#include <sys/param.h>
32#include <sys/bus.h>
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2016 Oleksandr Tymoshenko <gonzo@FreeBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 16 unchanged lines hidden (view full) ---

25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include "opt_acpi.h"
30
31#include <sys/param.h>
32#include <sys/bus.h>
33#include <sys/kdb.h>
33#include <sys/kernel.h>
34#include <sys/module.h>
35#include <sys/proc.h>
36#include <sys/rman.h>
37
38#include <machine/bus.h>
39#include <machine/resource.h>
40
41#include <dev/spibus/spi.h>
42#include <dev/spibus/spibusvar.h>
43
44#include <dev/intel/spi.h>
45
46/**
47 * Macros for driver mutex locking
48 */
34#include <sys/kernel.h>
35#include <sys/module.h>
36#include <sys/proc.h>
37#include <sys/rman.h>
38
39#include <machine/bus.h>
40#include <machine/resource.h>
41
42#include <dev/spibus/spi.h>
43#include <dev/spibus/spibusvar.h>
44
45#include <dev/intel/spi.h>
46
47/**
48 * Macros for driver mutex locking
49 */
49#define INTELSPI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
50#define INTELSPI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
50#define INTELSPI_IN_POLLING_MODE() (SCHEDULER_STOPPED() || kdb_active)
51#define INTELSPI_LOCK(_sc) do { \
52 if(!INTELSPI_IN_POLLING_MODE()) \
53 mtx_lock(&(_sc)->sc_mtx); \
54} while (0)
55#define INTELSPI_UNLOCK(_sc) do { \
56 if(!INTELSPI_IN_POLLING_MODE()) \
57 mtx_unlock(&(_sc)->sc_mtx); \
58} while (0)
51#define INTELSPI_LOCK_INIT(_sc) \
52 mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
53 "intelspi", MTX_DEF)
54#define INTELSPI_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
59#define INTELSPI_LOCK_INIT(_sc) \
60 mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
61 "intelspi", MTX_DEF)
62#define INTELSPI_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
55#define INTELSPI_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
56#define INTELSPI_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED)
63#define INTELSPI_ASSERT_LOCKED(_sc) do { \
64 if(!INTELSPI_IN_POLLING_MODE()) \
65 mtx_assert(&(_sc)->sc_mtx, MA_OWNED); \
66} while (0)
67#define INTELSPI_ASSERT_UNLOCKED(_sc) do { \
68 if(!INTELSPI_IN_POLLING_MODE()) \
69 mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED);\
70} while (0)
57
58#define INTELSPI_WRITE(_sc, _off, _val) \
59 bus_write_4((_sc)->sc_mem_res, (_off), (_val))
60#define INTELSPI_READ(_sc, _off) \
61 bus_read_4((_sc)->sc_mem_res, (_off))
62
63#define INTELSPI_BUSY 0x1
64#define TX_FIFO_THRESHOLD 2

--- 272 unchanged lines hidden (view full) ---

337
338 KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
339 ("TX/RX command sizes should be equal"));
340 KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
341 ("TX/RX data sizes should be equal"));
342
343 INTELSPI_LOCK(sc);
344
71
72#define INTELSPI_WRITE(_sc, _off, _val) \
73 bus_write_4((_sc)->sc_mem_res, (_off), (_val))
74#define INTELSPI_READ(_sc, _off) \
75 bus_read_4((_sc)->sc_mem_res, (_off))
76
77#define INTELSPI_BUSY 0x1
78#define TX_FIFO_THRESHOLD 2

--- 272 unchanged lines hidden (view full) ---

351
352 KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
353 ("TX/RX command sizes should be equal"));
354 KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
355 ("TX/RX data sizes should be equal"));
356
357 INTELSPI_LOCK(sc);
358
345 /* If the controller is in use wait until it is available. */
346 while (sc->sc_flags & INTELSPI_BUSY) {
347 if ((cmd->flags & SPI_FLAG_NO_SLEEP) == SPI_FLAG_NO_SLEEP) {
348 INTELSPI_UNLOCK(sc);
349 return (EBUSY);
359 if (!INTELSPI_IN_POLLING_MODE()) {
360 /* If the controller is in use wait until it is available. */
361 while (sc->sc_flags & INTELSPI_BUSY) {
362 if ((cmd->flags & SPI_FLAG_NO_SLEEP) != 0) {
363 INTELSPI_UNLOCK(sc);
364 return (EBUSY);
365 }
366 err = mtx_sleep(dev, &sc->sc_mtx, 0, "intelspi", 0);
367 if (err == EINTR) {
368 INTELSPI_UNLOCK(sc);
369 return (err);
370 }
350 }
371 }
351 err = mtx_sleep(dev, &sc->sc_mtx, 0, "intelspi", 0);
352 if (err == EINTR) {
353 INTELSPI_UNLOCK(sc);
354 return (err);
355 }
372 } else {
373 /*
374 * Now we are in the middle of other transfer. Try to reset
375 * controller state to get predictable context.
376 */
377 if ((sc->sc_flags & INTELSPI_BUSY) != 0)
378 intelspi_init(sc);
356 }
357
358 /* Now we have control over SPI controller. */
359 sc->sc_flags = INTELSPI_BUSY;
360
361 /* Configure the clock rate and SPI mode. */
362 spibus_get_clock(child, &clock);
363 spibus_get_mode(child, &mode);

--- 42 unchanged lines hidden (view full) ---

406 /* Enable CS */
407 intelspi_set_cs(sc, CS_LOW);
408
409 /* Wait the CS delay */
410 spibus_get_cs_delay(child, &cs_delay);
411 DELAY(cs_delay);
412
413 /* Transfer as much as possible to FIFOs */
379 }
380
381 /* Now we have control over SPI controller. */
382 sc->sc_flags = INTELSPI_BUSY;
383
384 /* Configure the clock rate and SPI mode. */
385 spibus_get_clock(child, &clock);
386 spibus_get_mode(child, &mode);

--- 42 unchanged lines hidden (view full) ---

429 /* Enable CS */
430 intelspi_set_cs(sc, CS_LOW);
431
432 /* Wait the CS delay */
433 spibus_get_cs_delay(child, &cs_delay);
434 DELAY(cs_delay);
435
436 /* Transfer as much as possible to FIFOs */
414 if ((cmd->flags & SPI_FLAG_NO_SLEEP) == SPI_FLAG_NO_SLEEP) {
437 if ((cmd->flags & SPI_FLAG_NO_SLEEP) != 0 ||
438 INTELSPI_IN_POLLING_MODE() || cold) {
415 /* We cannot wait with mtx_sleep if we're called from e.g. an ithread */
416 poll_limit = 2000;
417 while (!intelspi_transact(sc) && poll_limit-- > 0)
418 DELAY(1000);
419 if (poll_limit == 0) {
420 device_printf(dev, "polling was stuck, transaction not finished\n");
421 err = EIO;
422 }

--- 21 unchanged lines hidden (view full) ---

444
445 /* Make sure the SPI engine and interrupts are disabled. */
446 sscr1 = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR1);
447 sscr1 &= ~(SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE);
448 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR1, sscr1);
449
450 /* Release the controller and wakeup the next thread waiting for it. */
451 sc->sc_flags = 0;
439 /* We cannot wait with mtx_sleep if we're called from e.g. an ithread */
440 poll_limit = 2000;
441 while (!intelspi_transact(sc) && poll_limit-- > 0)
442 DELAY(1000);
443 if (poll_limit == 0) {
444 device_printf(dev, "polling was stuck, transaction not finished\n");
445 err = EIO;
446 }

--- 21 unchanged lines hidden (view full) ---

468
469 /* Make sure the SPI engine and interrupts are disabled. */
470 sscr1 = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR1);
471 sscr1 &= ~(SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE);
472 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR1, sscr1);
473
474 /* Release the controller and wakeup the next thread waiting for it. */
475 sc->sc_flags = 0;
452 wakeup_one(dev);
476 if (!INTELSPI_IN_POLLING_MODE())
477 wakeup_one(dev);
453 INTELSPI_UNLOCK(sc);
454
455 /*
456 * Check for transfer timeout. The SPI controller doesn't
457 * return errors.
458 */
459 if (err == EWOULDBLOCK) {
460 device_printf(sc->sc_dev, "transfer timeout\n");

--- 132 unchanged lines hidden ---
478 INTELSPI_UNLOCK(sc);
479
480 /*
481 * Check for transfer timeout. The SPI controller doesn't
482 * return errors.
483 */
484 if (err == EWOULDBLOCK) {
485 device_printf(sc->sc_dev, "transfer timeout\n");

--- 132 unchanged lines hidden ---