]> git.ipfire.org Git - thirdparty/openwrt.git/blob
18bd7657013373fe17e9bfa2d6f14357e39e6c8e
[thirdparty/openwrt.git] /
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
5 DMA burst constraints
6
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.
10
11 For DMA engines with restricted capabilities the requested burst length
12 and FIFO thresholds need to be adjusted downward accordingly.
13
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.
16
17 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
18 ---
19 sound/soc/dwc/dwc-i2s.c | 21 ++++++++++++++++-----
20 sound/soc/dwc/local.h | 1 +
21 2 files changed, 17 insertions(+), 5 deletions(-)
22
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_
26 u32 ch_reg;
27 struct i2s_clk_config_data *config = &dev->config;
28 u32 dmacr;
29 + u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
30 + u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
31
32 i2s_disable_channels(dev, stream);
33
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),
38 - dev->fifo_th - 1);
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;
61 + else
62 + dev->play_dma_data.dt.maxburst = fifo_depth / 2;
63 }
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;
73 + else
74 + dev->capture_dma_data.dt.maxburst = fifo_depth / 2;
75 }
76
77 + if (dev->max_dma_burst)
78 + dev->fifo_th = min(dev->max_dma_burst, dev->fifo_th);
79 return 0;
80
81 }
82 @@ -1069,6 +1079,7 @@ static int dw_i2s_probe(struct platform_
83 }
84 }
85
86 + of_property_read_u32(pdev->dev.of_node, "dma-maxburst", &dev->max_dma_burst);
87 dev->bclk_ratio = 0;
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 {
93 u32 ccr;
94 u32 xfer_resolution;
95 u32 fifo_th;
96 + u32 max_dma_burst;
97 u32 l_reg;
98 u32 r_reg;
99 bool is_jh7110; /* Flag for StarFive JH7110 SoC */