1 From b6b4260fa546d1dc7421c7cfed059052dae04227 Mon Sep 17 00:00:00 2001
2 From: Jonathan Bell <jonathan@raspberrypi.com>
3 Date: Thu, 18 Jul 2024 09:40:03 +0100
4 Subject: [PATCH 1197/1215] sound/soc: dwc-i2s: choose FIFO thresholds based on
7 Valid ranges for the I2S peripheral's FIFO configuration include a depth
8 of 16 - unconditionally setting the burst length to 16 with a fifo
9 threshold of size/2 will cause under/overflows.
11 For DMA engines with restricted capabilities the requested burst length
12 and FIFO thresholds need to be adjusted downward accordingly.
14 Both the RX and TX FIFOs operate on "less-than" thresholds. Setting the
15 TX threshold to fifo_size minus burst means the FIFO is kept nearly-full.
17 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
19 sound/soc/dwc/dwc-i2s.c | 21 ++++++++++++++++-----
20 sound/soc/dwc/local.h | 1 +
21 2 files changed, 17 insertions(+), 5 deletions(-)
23 --- a/sound/soc/dwc/dwc-i2s.c
24 +++ b/sound/soc/dwc/dwc-i2s.c
25 @@ -235,6 +235,8 @@ static void dw_i2s_config(struct dw_i2s_
27 struct i2s_clk_config_data *config = &dev->config;
29 + u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
30 + u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
32 i2s_disable_channels(dev, stream);
34 @@ -250,7 +252,7 @@ static void dw_i2s_config(struct dw_i2s_
35 i2s_write_reg(dev->i2s_base, TCR(ch_reg),
36 dev->xfer_resolution);
37 i2s_write_reg(dev->i2s_base, TFCR(ch_reg),
39 + fifo_depth - dev->fifo_th - 1);
40 i2s_write_reg(dev->i2s_base, TER(ch_reg), TER_TXCHEN |
41 dev->tdm_mask << TER_TXSLOT_SHIFT);
42 dmacr |= (DMACR_DMAEN_TXCH0 << ch_reg);
43 @@ -782,8 +784,8 @@ static int dw_configure_dai_by_pd(struct
44 dev->capture_dma_data.pd.data = pdata->capture_dma_data;
45 dev->play_dma_data.pd.addr = res->start + I2S_TXDMA;
46 dev->capture_dma_data.pd.addr = res->start + I2S_RXDMA;
47 - dev->play_dma_data.pd.max_burst = 16;
48 - dev->capture_dma_data.pd.max_burst = 16;
49 + dev->play_dma_data.pd.max_burst = dev->fifo_th;
50 + dev->capture_dma_data.pd.max_burst = dev->fifo_th;
51 dev->play_dma_data.pd.addr_width = bus_widths[idx];
52 dev->capture_dma_data.pd.addr_width = bus_widths[idx];
53 dev->play_dma_data.pd.filter = pdata->filter;
54 @@ -814,7 +816,10 @@ static int dw_configure_dai_by_dt(struct
55 dev->play_dma_data.dt.addr = res->start + I2S_TXDMA;
56 dev->play_dma_data.dt.fifo_size = fifo_depth *
57 (fifo_width[idx2]) >> 8;
58 - dev->play_dma_data.dt.maxburst = 16;
59 + if (dev->max_dma_burst)
60 + dev->play_dma_data.dt.maxburst = dev->max_dma_burst;
62 + dev->play_dma_data.dt.maxburst = fifo_depth / 2;
64 if (COMP1_RX_ENABLED(comp1)) {
65 idx2 = COMP2_RX_WORDSIZE_0(comp2);
66 @@ -823,9 +828,14 @@ static int dw_configure_dai_by_dt(struct
67 dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA;
68 dev->capture_dma_data.dt.fifo_size = fifo_depth *
69 (fifo_width[idx2] >> 8);
70 - dev->capture_dma_data.dt.maxburst = 16;
71 + if (dev->max_dma_burst)
72 + dev->capture_dma_data.dt.maxburst = dev->max_dma_burst;
74 + dev->capture_dma_data.dt.maxburst = fifo_depth / 2;
77 + if (dev->max_dma_burst)
78 + dev->fifo_th = min(dev->max_dma_burst, dev->fifo_th);
82 @@ -1069,6 +1079,7 @@ static int dw_i2s_probe(struct platform_
86 + of_property_read_u32(pdev->dev.of_node, "dma-maxburst", &dev->max_dma_burst);
88 dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
89 dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
90 --- a/sound/soc/dwc/local.h
91 +++ b/sound/soc/dwc/local.h
92 @@ -133,6 +133,7 @@ struct dw_i2s_dev {
99 bool is_jh7110; /* Flag for StarFive JH7110 SoC */