History

spi: Add a PTP system timestamp to the transfer structure

SPI is one of the interfaces used to access devices which have a POSIX clock driver (real time clocks, 1588 timers etc). The fact that the SPI bus is slow is not what the main problem is, but rather the fact that drivers don't take a constant amount of time in transferring data over SPI. When there is a high delay in the readout of time, there will be uncertainty in the value that has been read out of the peripheral. When that delay is constant, the uncertainty can at least be approximated with a certain accuracy which is fine more often than not. Timing jitter occurs all over in the kernel code, and is mainly caused by having to let go of the CPU for various reasons such as preemption, servicing interrupts, going to sleep, etc. Another major reason is CPU dynamic frequency scaling. It turns out that the problem of retrieving time from a SPI peripheral with high accuracy can be solved by the use of "PTP system timestamping" - a mechanism to correlate the time when the device has snapshotted its internal time counter with the Linux system time at that same moment. This is sufficient for having a precise time measurement - it is not necessary for the whole SPI transfer to be transmitted "as fast as possible", or "as low-jitter as possible". The system has to be low-jitter for a very short amount of time to be effective. This patch introduces a PTP system timestamping mechanism in struct spi_transfer. This is to be used by SPI device drivers when they need to know the exact time at which the underlying device's time was snapshotted. More often than not, SPI peripherals have a very exact timing for when their SPI-to-interconnect bridge issues a transaction for snapshotting and reading the time register, and that will be dependent on when the SPI-to-interconnect bridge figures out that this is what it should do, aka as soon as it sees byte N of the SPI transfer. Since spi_device drivers are the ones who'd know best how the peripheral behaves in this regard, expose a mechanism in spi_transfer which allows them to specify which word (or word range) from the transfer should be timestamped. Add a default implementation of the PTP system timestamping in the SPI core. This is not going to be satisfactory performance-wise, but should at least increase the likelihood that SPI device drivers will use PTP system timestamping in the future. There are 3 entry points from the core towards the SPI controller drivers: - transfer_one: The driver is passed individual spi_transfers to execute. This is the easiest to timestamp. - transfer_one_message: The core passes the driver an entire spi_message (a potential batch of spi_transfers). The core puts the same pre and post timestamp to all transfers within a message. This is not ideal, but nothing better can be done by default anyway, since the core has no insight into how the driver batches the transfers. - transfer: Like transfer_one_message, but for unqueued drivers (i.e. the driver implements its own queue scheduling).

Vladimir Oltean committed 7 years ago

Commit b42faee1 parent 62217f82 files · +188 −0Browse files

Showing the changes to include/linux (1 of 2 files). Show all

Unified · Split

include/linux/spi/spi.h+61−0
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include <linux/completion.h>
1414 #include <linux/scatterlist.h>
1515 #include <linux/gpio/consumer.h>
16+#include <linux/ptp_clock_kernel.h>
1617
1718 struct dma_chan;
1819 struct property_entry;
@@ -409,6 +410,12 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) · 390 unmodified lines
409410 * @fw_translate_cs: If the boot firmware uses different numbering scheme
410411 * what Linux expects, this optional hook can be used to translate
411412 * between the two.
413+ * @ptp_sts_supported: If the driver sets this to true, it must provide a
414+ * time snapshot in @spi_transfer->ptp_sts as close as possible to the
415+ * moment in time when @spi_transfer->ptp_sts_word_pre and
416+ * @spi_transfer->ptp_sts_word_post were transmitted.
417+ * If the driver does not set this, the SPI core takes the snapshot as
418+ * close to the driver hand-over as possible.
412419 *
413420 * Each SPI controller can communicate with one or more @spi_device
414421 * children. These make a small bus, sharing MOSI, MISO and SCK signals
@@ -604,6 +611,15 @@ struct spi_controller { · 189 unmodified lines
604611 void *dummy_tx;
605612
606613 int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs);
614+
615+ /*
616+ * Driver sets this field to indicate it is able to snapshot SPI
617+ * transfers (needed e.g. for reading the time of POSIX clocks)
618+ */
619+ bool ptp_sts_supported;
620+
621+ /* Interrupt enable state during PTP system timestamping */
622+ unsigned long irq_flags;
607623 };
608624
609625 static inline void *spi_controller_get_devdata(struct spi_controller *ctlr)
@@ -644,6 +660,14 @@ extern struct spi_message *spi_get_next_queued_message(struct spi_controller *ct · 34 unmodified lines
644660 extern void spi_finalize_current_message(struct spi_controller *ctlr);
645661 extern void spi_finalize_current_transfer(struct spi_controller *ctlr);
646662
663+/* Helper calls for driver to timestamp transfer */
664+void spi_take_timestamp_pre(struct spi_controller *ctlr,
665+ struct spi_transfer *xfer,
666+ const void *tx, bool irqs_off);
667+void spi_take_timestamp_post(struct spi_controller *ctlr,
668+ struct spi_transfer *xfer,
669+ const void *tx, bool irqs_off);
670+
647671 /* the spi driver core manages memory for the spi_controller classdev */
648672 extern struct spi_controller *__spi_alloc_controller(struct device *host,
649673 unsigned int size, bool slave);
@@ -753,6 +777,35 @@ extern void spi_res_release(struct spi_controller *ctlr, · 103 unmodified lines
753777 * @transfer_list: transfers are sequenced through @spi_message.transfers
754778 * @tx_sg: Scatterlist for transmit, currently not for client use
755779 * @rx_sg: Scatterlist for receive, currently not for client use
780+ * @ptp_sts_word_pre: The word (subject to bits_per_word semantics) offset
781+ * within @tx_buf for which the SPI device is requesting that the time
782+ * snapshot for this transfer begins. Upon completing the SPI transfer,
783+ * this value may have changed compared to what was requested, depending
784+ * on the available snapshotting resolution (DMA transfer,
785+ * @ptp_sts_supported is false, etc).
786+ * @ptp_sts_word_post: See @ptp_sts_word_post. The two can be equal (meaning
787+ * that a single byte should be snapshotted).
788+ * If the core takes care of the timestamp (if @ptp_sts_supported is false
789+ * for this controller), it will set @ptp_sts_word_pre to 0, and
790+ * @ptp_sts_word_post to the length of the transfer. This is done
791+ * purposefully (instead of setting to spi_transfer->len - 1) to denote
792+ * that a transfer-level snapshot taken from within the driver may still
793+ * be of higher quality.
794+ * @ptp_sts: Pointer to a memory location held by the SPI slave device where a
795+ * PTP system timestamp structure may lie. If drivers use PIO or their
796+ * hardware has some sort of assist for retrieving exact transfer timing,
797+ * they can (and should) assert @ptp_sts_supported and populate this
798+ * structure using the ptp_read_system_*ts helper functions.
799+ * The timestamp must represent the time at which the SPI slave device has
800+ * processed the word, i.e. the "pre" timestamp should be taken before
801+ * transmitting the "pre" word, and the "post" timestamp after receiving
802+ * transmit confirmation from the controller for the "post" word.
803+ * @timestamped_pre: Set by the SPI controller driver to denote it has acted
804+ * upon the @ptp_sts request. Not set when the SPI core has taken care of
805+ * the task. SPI device drivers are free to print a warning if this comes
806+ * back unset and they need the better resolution.
807+ * @timestamped_post: See above. The reason why both exist is that these
808+ * booleans are also used to keep state in the core SPI logic.
756809 *
757810 * SPI transfers always write the same number of bytes as they read.
758811 * Protocol drivers should always provide @rx_buf and/or @tx_buf.
@@ -842,6 +895,14 @@ struct spi_transfer { · 83 unmodified lines
842895
843896 u32 effective_speed_hz;
844897
898+ unsigned int ptp_sts_word_pre;
899+ unsigned int ptp_sts_word_post;
900+
901+ struct ptp_system_timestamp *ptp_sts;
902+
903+ bool timestamped_pre;
904+ bool timestamped_post;
905+
845906 struct list_head transfer_list;
846907 };
847908

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t