Skip to content

Commit f7c7657

Browse files
author
Tomasz Bursztyka
committed
spi: Add API support for DDR, Dual, Quad and Octal modes
These modes are present on more advanced and recent SPI controller. Though dual, quand and octal were present on configuration side already, it could not work with the standard command/address/data format which is now addressed via these changes. Also adding a way to make use of hardware optimizations for SPI flash JEDEC devices which seem to be largely present in various SPI controllers. Note, however, that these new SPI API modes are not meant to be used by QSPI flash controllers: for these, a dedicated flash controller driver will still be the preferred solution. Fixes #17902 Signed-off-by: Tomasz Bursztyka <[email protected]>
1 parent b3e67cf commit f7c7657

File tree

2 files changed

+156
-6
lines changed

2 files changed

+156
-6
lines changed

drivers/spi/Kconfig

+2-4
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ config SPI_EXTENDED_MODES
3838
bool "Extended modes [EXPERIMENTAL]"
3939
select EXPERIMENTAL
4040
help
41-
Enables extended operations in the SPI API. Currently, this
42-
enables the possibility to select the line mode (single/dual/
43-
quad/octal), though none of these mode are really supported as
44-
it would require more features exposed into the SPI buffer.
41+
Enables extended operations in the SPI API: Double Data Rate and
42+
dual/quad/octal modes.
4543

4644
config SPI_INIT_PRIORITY
4745
int "Init priority"

include/zephyr/drivers/spi.h

+154-2
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,10 @@ extern "C" {
133133
* @name SPI MISO lines
134134
* @{
135135
*
136-
* Some controllers support dual, quad or octal MISO lines connected to slaves.
136+
* Some controllers, in addition to standard single line, support dual, quad
137+
* or octal MISO lines connected to slaves. Note that these SPI API modes are
138+
* not meant to be used by QSPI flash controllers: for these, a dedicated
139+
* flash controller driver will still be the preferred solution.
137140
* Default is single, which is the case most of the time.
138141
* Without @kconfig{CONFIG_SPI_EXTENDED_MODES} being enabled, single is the
139142
* only supported one.
@@ -147,6 +150,16 @@ extern "C" {
147150

148151
/** @} */
149152

153+
/**
154+
* @name SPI extended modes enabler bit
155+
* @{
156+
* In order to use the extended modes, this bit must be set. Or else, the
157+
* SPI controller driver will not look at the added struct spi_buf's flags
158+
* attribute.
159+
*/
160+
#define SPI_EXTENDED_MODES BIT(18)
161+
/** @} */
162+
150163
/**
151164
* @brief SPI Chip Select control structure
152165
*
@@ -317,7 +330,8 @@ struct spi_config {
317330
* If @kconfig{CONFIG_SPI_EXTENDED_MODES} is enabled:
318331
*
319332
* - 16..17: MISO lines (Single/Dual/Quad/Octal).
320-
* - 18..31: Reserved for future use.
333+
* - 18 Extended modes are in use
334+
* - 19..31: Reserved for future use.
321335
*/
322336
spi_operation_t operation;
323337
/** @brief Slave number from 0 to host controller slave limit. */
@@ -417,6 +431,131 @@ struct spi_dt_spec {
417431
#define SPI_DT_SPEC_INST_GET(inst, operation_, delay_) \
418432
SPI_DT_SPEC_GET(DT_DRV_INST(inst), operation_, delay_)
419433

434+
/**
435+
* @name SPI Extended Mode flags: Double Data Rate, Dual/Quad/Octal modes
436+
* (Respectively DDR and DQO)
437+
* @{
438+
*/
439+
440+
/**
441+
* SPI Command phase is send via standard mode (single line)
442+
* spi_config lines bit field will be superseded by this flag only
443+
* for the command.
444+
*/
445+
#define SPI_EM_CMD_STD BIT(0)
446+
/**
447+
* SPI Command phase is send via extended modes (double/quad/octal)
448+
* The mode will depend on the spi_config's lines bit field.
449+
*/
450+
#define SPI_EM_CMD_DQO BIT(1)
451+
/**
452+
* SPI Command phase will take advantage of Double Data Rate
453+
* Use it with SPI_EM_CMD_STD or SPI_EM_CMD_DQO relevantly. Or prefer using
454+
* SPI_EM_CMD_STD_DDR or SPI_EM_CMD_DQO_DDR below.
455+
*/
456+
#define SPI_EM_CMD_DDR BIT(2)
457+
/**
458+
* SPI Command phase is send via standard mode in Double Data Rate
459+
*/
460+
#define SPI_EM_CMD_STD_DDR (SPI_EM_CMD_STD | SPI_EM_CMD_DDR)
461+
/**
462+
* SPI Command phase is send via extended modes in Double Data Rate
463+
*/
464+
#define SPI_EM_CMD_DQO_DDR (SPI_EM_CMD_DBO | SPI_EM_CMD_DDR)
465+
466+
/**
467+
* SPI Addressing phase is send via standard mode (single line)
468+
* spi_config's lines bit field will be superseded by this flag only
469+
* for the address.
470+
*/
471+
#define SPI_EM_ADDR_STD BIT(3)
472+
/**
473+
* SPI Addressing phase is send via extended modes (double/quad/octal)
474+
* The mode will depend on the spi_config's lines bit field.
475+
*/
476+
#define SPI_EM_ADDR_DQO BIT(4)
477+
/**
478+
* SPI Addressing phase will take advantage of Double Data Rate
479+
* Use it with SPI_EM_ADDR_STD or SPI_EM_ADDR_DQO relevantly. Or prefer using
480+
* SPI_EM_ADDR_STD_DDR or SPI_EM_ADDR_DQO_DDR.
481+
*/
482+
#define SPI_EM_ADDR_DDR BIT(5)
483+
/**
484+
* SPI Addressing phase is send via standard mode in Double Data Rate
485+
*/
486+
#define SPI_EM_ADDR_STD_DDR (SPI_EM_ADDR_STD | SPI_EM_ADDR_DDR)
487+
/**
488+
* SPI Addressing phase is send via extended modes in Double Data Rate
489+
*/
490+
#define SPI_EM_ADDR_DQO_DDR (SPI_EM_ADDR_DQO | SPI_EM_ADDR_DDR)
491+
492+
/**
493+
* SPI Data phase will take advantage of Double Data Rate
494+
*/
495+
#define SPI_EM_DATA_DDR BIT(6)
496+
497+
/**
498+
* SPI Command phase length configuration
499+
*/
500+
enum spi_em_cmd_length {
501+
SPI_EM_CMD_NONE = 0,
502+
SPI_EM_CMD_LEN_4_BITS,
503+
SPI_EM_CMD_LEN_8_BITS,
504+
SPI_EM_CMD_LEN_16_BITS
505+
};
506+
507+
#define SPI_EM_CMD_LENGTH_SHIFT (20)
508+
#define SPI_EM_CMD_LENGTH_MASK (0x03 << SPI_EM_CMD_LENGTH_SHIFT)
509+
510+
#define SPI_EM_CMD_LENGTH(_cfg_) \
511+
(((_cfg_) & SPI_EM_CMD_LENGTH_MASK) >> SPI_EM_CMD_LENGTH_SHIFT)
512+
513+
#define SPI_EM_CMD_LENGTH_SET(_len_) \
514+
((_len_) << SPI_EM_CMD_LENGTH_SHIFT)
515+
516+
/**
517+
* SPI Addressing phase length configuration
518+
*/
519+
enum spi_em_adr_length {
520+
SPI_EM_ADDR_NONE = 0,
521+
SPI_EM_ADDR_LEN_4_BITS,
522+
SPI_EM_ADDR_LEN_8_BITS,
523+
SPI_EM_ADDR_LEN_12_BITS,
524+
SPI_EM_ADDR_LEN_16_BITS,
525+
SPI_EM_ADDR_LEN_20_BITS,
526+
SPI_EM_ADDR_LEN_24_BITS,
527+
SPI_EM_ADDR_LEN_28_BITS,
528+
SPI_EM_ADDR_LEN_32_BITS,
529+
SPI_EM_ADDR_LEN_36_BITS,
530+
SPI_EM_ADDR_LEN_40_BITS,
531+
SPI_EM_ADDR_LEN_44_BITS,
532+
SPI_EM_ADDR_LEN_48_BITS,
533+
SPI_EM_ADDR_LEN_52_BITS,
534+
SPI_EM_ADDR_LEN_56_BITS,
535+
SPI_EM_ADDR_LEN_60_BITS,
536+
SPI_EM_ADDR_LEN_64_BITS
537+
};
538+
539+
#define SPI_EM_ADDR_LENGTH_SHIFT (22)
540+
#define SPI_EM_ADDR_LENGTH_MASK (0x1F << SPI_EM_ADDR_LENGTH_SHIFT)
541+
542+
#define SPI_EM_ADDR_LENGTH(_cfg_) \
543+
(((_cfg_) & SPI_EM_ADDR_LENGTH_MASK) >> SPI_EM_ADDR_LENGTH_SHIFT)
544+
545+
#define SPI_EM_ADDR_LENGTH_SET(_len_) \
546+
((_len_) << SPI_EM_ADDR_LENGTH_SHIFT)
547+
548+
#define SPI_EM_WAIT_CYCLE_SHIFT (27)
549+
#define SPI_EM_WAIT_CYCLE_MASK (0x1F << SPI_EM_WAIT_CYCLE_SHIFT)
550+
551+
#define SPI_EM_WAIT_CYCLE(_cfg_) \
552+
(((_cfg_) & SPI_EM_WAIT_CYCLE_MASK) >> SPI_EM_WAIT_CYCLE_SHIFT)
553+
554+
#define SPI_EM_WAIT_CYCLE_SET(_wc_) \
555+
((_wc_) << SPI_EM_WAIT_CYCLE_SHIFT)
556+
557+
/** @} */
558+
420559
/**
421560
* @brief SPI buffer structure
422561
*/
@@ -428,6 +567,19 @@ struct spi_buf {
428567
* buffer) or the length of bytes that should be skipped (as RX buffer).
429568
*/
430569
size_t len;
570+
#ifdef CONFIG_SPI_EXTENDED_MODES
571+
/** Optional attribute for ddr/dual/quad and octal modes.
572+
* The SPI controller driver will only look at it if, and only if,
573+
* extended_modes bit in struct spi_config's operation attribute if set.
574+
* This attribute is a bit field with following parts:
575+
* config [0:19] - See SPI extended mode flags above
576+
* bits 7 to 19 are reserved for future use.
577+
* command length [20:21] - 2 bits factor command length
578+
* address length [22:26] - 5 bits factor address length
579+
* wait cycles [27:31] - 5 bits RX wait cycles (from 0 to 32)
580+
*/
581+
uint32_t flags;
582+
#endif
431583
};
432584

433585
/**

0 commit comments

Comments
 (0)