Skip to content

Commit 36f8f18

Browse files
committed
Merge series "spi: dw: Add generic DW DMA controller support" from Serge Semin <[email protected]>:
Baikal-T1 SoC provides a DW DMA controller to perform low-speed peripherals Mem-to-Dev and Dev-to-Mem transaction. This is also applicable to the DW APB SSI devices embedded into the SoC. Currently the DMA-based transfers are supported by the DW APB SPI driver only as a middle layer code for Intel MID/Elkhart PCI devices. Seeing the same code can be used for normal platform DMAC device we introduced a set of patches to fix it within this series. First of all we need to add the Tx and Rx DMA channels support into the DW APB SSI binding. Then there are several fixes and cleanups provided as a initial preparation for the Generic DMA support integration: add Tx/Rx finish wait methods, clear DMAC register when done or stopped, Fix native CS being unset, enable interrupts in accordance with DMA xfer mode, discard static DW DMA slave structures, discard unused void priv pointer and dma_width member of the dw_spi structure, provide the DMA Tx/Rx burst length parametrisation and make sure it's optionally set in accordance with the DMA max-burst capability. In order to have the DW APB SSI MMIO driver working with DMA we need to initialize the paddr field with the physical base address of the DW APB SSI registers space. Then we unpin the Intel MID specific code from the generic DMA one and placed it into the spi-dw-pci.c driver, which is a better place for it anyway. After that the naming cleanups are performed since the code is going to be used for a generic DMAC device. Finally the Generic DMA initialization can be added to the generic version of the DW APB SSI IP. Last but not least we traditionally convert the legacy plain text-based dt-binding file with yaml-based one and as a cherry on a cake replace the manually written DebugFS registers read method with a ready-to-use for the same purpose regset32 DebugFS interface usage. This patchset is rebased and tested on the spi/for-next (5.7-rc5): base-commit: fe9fce6 ("Merge remote-tracking branch 'spi/for-5.8' into spi-next") Link: https://lore.kernel.org/linux-spi/[email protected]/ Changelog v2: - Rebase on top of the spi repository for-next branch. - Move bindings conversion patch to the tail of the series. - Move fixes to the head of the series. - Apply as many changes as possible to be applied the Generic DMA functionality support is added and the spi-dw-mid is moved to the spi-dw-dma driver. - Discard patch "spi: dw: Fix dma_slave_config used partly uninitialized" since the problem has already been fixed. - Add new patch "spi: dw: Discard unused void priv pointer". - Add new patch "spi: dw: Discard dma_width member of the dw_spi structure". n_bytes member of the DW SPI data can be used instead. - Build the DMA functionality into the DW APB SSI core if required instead of creating a separate kernel module. - Use conditional statement instead of the ternary operator in the ref clock getter. Link: https://lore.kernel.org/linux-spi/[email protected]/ Changelog v3: - Use spi_delay_exec() method to wait for the DMA operation completion. - Explicitly initialize the dw_dma_slave members on stack. - Discard the dws->fifo_len utilization in the Tx FIFO DMA threshold setting from the patch where we just add the default burst length constants. - Use min() method to calculate the optimal burst values. - Add new patch which moves the spi-dw.c source file to spi-dw-core.c in order to preserve the DW APB SSI core driver name. - Add commas in the debugfs_reg32 structure initializer and after the last entry of the dw_spi_dbgfs_regs array. Link: https://lore.kernel.org/linux-spi/[email protected] Changelog v4: - Get back ndelay() method to wait for an SPI transfer completion. spi_delay_exec() isn't suitable for the atomic context. Co-developed-by: Georgy Vlasov <[email protected]> Signed-off-by: Georgy Vlasov <[email protected]> Co-developed-by: Ramil Zaripov <[email protected]> Signed-off-by: Ramil Zaripov <[email protected]> Signed-off-by: Serge Semin <[email protected]> Cc: Alexey Malahov <[email protected]> Cc: Maxim Kaurkin <[email protected]> Cc: Pavel Parkhomenko <[email protected]> Cc: Ekaterina Skachko <[email protected]> Cc: Vadim Vlasov <[email protected]> Cc: Alexey Kolotnikov <[email protected]> Cc: Thomas Bogendoerfer <[email protected]> Cc: Paul Burton <[email protected]> Cc: Ralf Baechle <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Andy Shevchenko <[email protected]> Cc: Rob Herring <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Serge Semin (16): spi: dw: Add Tx/Rx finish wait methods to the MID DMA spi: dw: Enable interrupts in accordance with DMA xfer mode spi: dw: Discard static DW DMA slave structures spi: dw: Discard unused void priv pointer spi: dw: Discard dma_width member of the dw_spi structure spi: dw: Parameterize the DMA Rx/Tx burst length spi: dw: Use DMA max burst to set the request thresholds spi: dw: Fix Rx-only DMA transfers spi: dw: Add core suffix to the DW APB SSI core source file spi: dw: Move Non-DMA code to the DW PCIe-SPI driver spi: dw: Remove DW DMA code dependency from DW_DMAC_PCI spi: dw: Add DW SPI DMA/PCI/MMIO dependency on the DW SPI core spi: dw: Cleanup generic DW DMA code namings spi: dw: Add DMA support to the DW SPI MMIO driver spi: dw: Use regset32 DebugFS method to create regdump file dt-bindings: spi: Convert DW SPI binding to DT schema .../bindings/spi/snps,dw-apb-ssi.txt | 44 --- .../bindings/spi/snps,dw-apb-ssi.yaml | 127 +++++++++ .../devicetree/bindings/spi/spi-dw.txt | 24 -- drivers/spi/Kconfig | 15 +- drivers/spi/Makefile | 5 +- drivers/spi/{spi-dw.c => spi-dw-core.c} | 88 ++---- drivers/spi/{spi-dw-mid.c => spi-dw-dma.c} | 261 ++++++++++-------- drivers/spi/spi-dw-mmio.c | 4 + drivers/spi/spi-dw-pci.c | 50 +++- drivers/spi/spi-dw.h | 33 ++- 10 files changed, 392 insertions(+), 259 deletions(-) delete mode 100644 Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt create mode 100644 Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml delete mode 100644 Documentation/devicetree/bindings/spi/spi-dw.txt rename drivers/spi/{spi-dw.c => spi-dw-core.c} (82%) rename drivers/spi/{spi-dw-mid.c => spi-dw-dma.c} (55%) -- 2.25.1
2 parents 39690c8 + 4fdc03a commit 36f8f18

File tree

3 files changed

+21
-26
lines changed

3 files changed

+21
-26
lines changed

drivers/spi/spi-dw-mid.c

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
#define RX_BUSY 0
2121
#define TX_BUSY 1
2222

23-
static struct dw_dma_slave mid_dma_tx = { .dst_id = 1 };
24-
static struct dw_dma_slave mid_dma_rx = { .src_id = 0 };
25-
2623
static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param)
2724
{
2825
struct dw_dma_slave *s = param;
@@ -36,9 +33,11 @@ static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param)
3633

3734
static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
3835
{
36+
struct dw_dma_slave slave = {
37+
.src_id = 0,
38+
.dst_id = 0
39+
};
3940
struct pci_dev *dma_dev;
40-
struct dw_dma_slave *tx = dws->dma_tx;
41-
struct dw_dma_slave *rx = dws->dma_rx;
4241
dma_cap_mask_t mask;
4342

4443
/*
@@ -53,14 +52,14 @@ static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
5352
dma_cap_set(DMA_SLAVE, mask);
5453

5554
/* 1. Init rx channel */
56-
rx->dma_dev = &dma_dev->dev;
57-
dws->rxchan = dma_request_channel(mask, mid_spi_dma_chan_filter, rx);
55+
slave.dma_dev = &dma_dev->dev;
56+
dws->rxchan = dma_request_channel(mask, mid_spi_dma_chan_filter, &slave);
5857
if (!dws->rxchan)
5958
goto err_exit;
6059

6160
/* 2. Init tx channel */
62-
tx->dma_dev = &dma_dev->dev;
63-
dws->txchan = dma_request_channel(mask, mid_spi_dma_chan_filter, tx);
61+
slave.dst_id = 1;
62+
dws->txchan = dma_request_channel(mask, mid_spi_dma_chan_filter, &slave);
6463
if (!dws->txchan)
6564
goto free_rxchan;
6665

@@ -134,10 +133,10 @@ static bool mid_spi_can_dma(struct spi_controller *master,
134133
return xfer->len > dws->fifo_len;
135134
}
136135

137-
static enum dma_slave_buswidth convert_dma_width(u32 dma_width) {
138-
if (dma_width == 1)
136+
static enum dma_slave_buswidth convert_dma_width(u8 n_bytes) {
137+
if (n_bytes == 1)
139138
return DMA_SLAVE_BUSWIDTH_1_BYTE;
140-
else if (dma_width == 2)
139+
else if (n_bytes == 2)
141140
return DMA_SLAVE_BUSWIDTH_2_BYTES;
142141

143142
return DMA_SLAVE_BUSWIDTH_UNDEFINED;
@@ -173,7 +172,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws,
173172
txconf.dst_addr = dws->dma_addr;
174173
txconf.dst_maxburst = 16;
175174
txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
176-
txconf.dst_addr_width = convert_dma_width(dws->dma_width);
175+
txconf.dst_addr_width = convert_dma_width(dws->n_bytes);
177176
txconf.device_fc = false;
178177

179178
dmaengine_slave_config(dws->txchan, &txconf);
@@ -222,7 +221,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws,
222221
rxconf.src_addr = dws->dma_addr;
223222
rxconf.src_maxburst = 16;
224223
rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
225-
rxconf.src_addr_width = convert_dma_width(dws->dma_width);
224+
rxconf.src_addr_width = convert_dma_width(dws->n_bytes);
226225
rxconf.device_fc = false;
227226

228227
dmaengine_slave_config(dws->rxchan, &rxconf);
@@ -243,19 +242,23 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws,
243242

244243
static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer)
245244
{
246-
u16 dma_ctrl = 0;
245+
u16 imr = 0, dma_ctrl = 0;
247246

248247
dw_writel(dws, DW_SPI_DMARDLR, 0xf);
249248
dw_writel(dws, DW_SPI_DMATDLR, 0x10);
250249

251-
if (xfer->tx_buf)
250+
if (xfer->tx_buf) {
252251
dma_ctrl |= SPI_DMA_TDMAE;
253-
if (xfer->rx_buf)
252+
imr |= SPI_INT_TXOI;
253+
}
254+
if (xfer->rx_buf) {
254255
dma_ctrl |= SPI_DMA_RDMAE;
256+
imr |= SPI_INT_RXUI | SPI_INT_RXOI;
257+
}
255258
dw_writel(dws, DW_SPI_DMACR, dma_ctrl);
256259

257260
/* Set the interrupt mask */
258-
spi_umask_intr(dws, SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI);
261+
spi_umask_intr(dws, imr);
259262

260263
dws->transfer_handler = dma_transfer;
261264

@@ -313,8 +316,6 @@ static const struct dw_spi_dma_ops mfld_dma_ops = {
313316

314317
static void dw_spi_mid_setup_dma_mfld(struct dw_spi *dws)
315318
{
316-
dws->dma_tx = &mid_dma_tx;
317-
dws->dma_rx = &mid_dma_rx;
318319
dws->dma_ops = &mfld_dma_ops;
319320
}
320321

drivers/spi/spi-dw.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,6 @@ static int dw_spi_transfer_one(struct spi_controller *master,
353353
}
354354

355355
dws->n_bytes = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE);
356-
dws->dma_width = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE);
357356

358357
cr0 = dws->update_cr0(master, spi, transfer);
359358
dw_writel(dws, DW_SPI_CTRLR0, cr0);

drivers/spi/spi-dw.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ struct dw_spi {
136136
void *rx_end;
137137
int dma_mapped;
138138
u8 n_bytes; /* current is a 1/2 bytes op */
139-
u32 dma_width;
140139
irqreturn_t (*transfer_handler)(struct dw_spi *dws);
141140
u32 current_freq; /* frequency in hz */
142141

@@ -146,11 +145,7 @@ struct dw_spi {
146145
unsigned long dma_chan_busy;
147146
dma_addr_t dma_addr; /* phy address of the Data register */
148147
const struct dw_spi_dma_ops *dma_ops;
149-
void *dma_tx;
150-
void *dma_rx;
151148

152-
/* Bus interface info */
153-
void *priv;
154149
#ifdef CONFIG_DEBUG_FS
155150
struct dentry *debugfs;
156151
#endif

0 commit comments

Comments
 (0)