diff options
author | Damien Le Moal <damien.lemoal@wdc.com> | 2020-12-06 10:18:16 +0900 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2020-12-09 12:14:22 +0000 |
commit | a51acc2400d47df0f87e1f011c63266421c594b9 (patch) | |
tree | dd23073b184e3ce000377cc3ca2dd0ee5bb90930 /drivers/spi/spi-dw.h | |
parent | 7b14a272f9ac2438a85e59571fdb5a653d86430b (diff) | |
download | linux-a51acc2400d47df0f87e1f011c63266421c594b9.tar.gz linux-a51acc2400d47df0f87e1f011c63266421c594b9.tar.bz2 linux-a51acc2400d47df0f87e1f011c63266421c594b9.zip |
spi: dw: Add support for 32-bits max xfer size
The Synopsis DesignWare DW_apb_ssi specifications version 3.23 onward
define a 32-bits maximum transfer size synthesis parameter
(SSI_MAX_XFER_SIZE=32) in addition to the legacy 16-bits configuration
(SSI_MAX_XFER_SIZE=16) for SPI controllers. When SSI_MAX_XFER_SIZE=32,
the layout of the ctrlr0 register changes, moving the data frame format
field from bits [3..0] to bits [16..20], and the RX/TX FIFO word size
can be up to 32-bits.
To support this new format, introduce the DW SPI capability flag
DW_SPI_CAP_DFS32 to indicate that a controller is configured with
SSI_MAX_XFER_SIZE=32. Since SSI_MAX_XFER_SIZE is a controller synthesis
parameter not accessible through a register, the detection of this
parameter value is done in spi_hw_init() by writing and reading the
ctrlr0 register and testing the value of bits [3..0]. These bits are
ignored (unchanged) for SSI_MAX_XFER_SIZE=16, allowing the detection.
If a DFS32 capable SPI controller is detected, the new field dfs_offset
in struct dw_spi is set to SPI_DFS32_OFFSET (16).
dw_spi_update_config() is modified to set the data frame size field at
the correct position is the CTRLR0 register, as indicated by the
dfs_offset field of the dw_spi structure.
The DW_SPI_CAP_DFS32 flag is also unconditionally set for SPI slave
controllers, e.g. controllers that have the DW_SPI_CAP_DWC_SSI
capability flag set. However, for these ssi controllers, the dfs_offset
field is set to 0 as before (as per specifications).
Finally, for any controller with the DW_SPI_CAP_DFS32 capability flag
set, dw_spi_add_host() extends the value of bits_per_word_mask from
16-bits to 32-bits. dw_reader() and dw_writer() are also modified to
handle 32-bits iTX/RX FIFO words.
Suggested-by: Sean Anderson <seanga2@gmail.com>
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Acked-by: Serge Semin <fancer.lancer@gmail.com>
Link: https://lore.kernel.org/r/20201206011817.11700-3-damien.lemoal@wdc.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-dw.h')
-rw-r--r-- | drivers/spi/spi-dw.h | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index faf40cb66498..b665e040862c 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -9,6 +9,7 @@ #include <linux/io.h> #include <linux/scatterlist.h> #include <linux/spi/spi-mem.h> +#include <linux/bitfield.h> /* Register offsets */ #define DW_SPI_CTRLR0 0x00 @@ -41,6 +42,8 @@ /* Bit fields in CTRLR0 */ #define SPI_DFS_OFFSET 0 +#define SPI_DFS_MASK GENMASK(3, 0) +#define SPI_DFS32_OFFSET 16 #define SPI_FRF_OFFSET 4 #define SPI_FRF_SPI 0x0 @@ -121,6 +124,7 @@ enum dw_ssi_type { #define DW_SPI_CAP_CS_OVERRIDE BIT(0) #define DW_SPI_CAP_KEEMBAY_MST BIT(1) #define DW_SPI_CAP_DWC_SSI BIT(2) +#define DW_SPI_CAP_DFS32 BIT(3) /* Slave spi_transfer/spi_mem_op related */ struct dw_spi_cfg { @@ -148,6 +152,7 @@ struct dw_spi { unsigned long paddr; int irq; u32 fifo_len; /* depth of the FIFO buffer */ + unsigned int dfs_offset; /* CTRLR0 DFS field offset */ u32 max_mem_freq; /* max mem-ops bus freq */ u32 max_freq; /* max bus freq supported */ |