at91: kernel v5.15: copy config and patches from 5.10
[openwrt/openwrt.git] / target / linux / at91 / patches-5.15 / 153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch
1 From 36bb4f0ab8e7ef69cc11d4d888aa898223b0e901 Mon Sep 17 00:00:00 2001
2 From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
3 Date: Mon, 1 Mar 2021 19:09:04 +0200
4 Subject: [PATCH 153/247] ASoC: mchp-i2s-mcc: Add FIFOs support
5
6 I2S-MCC found on SAMA7G5 includes 2 FIFOs (capture and playback). When
7 FIFOs are enabled, bits I2SMCC_ISRA.TXLRDYx and I2SMCC_ISRA.TXRRDYx must
8 not be used. Bits I2SMCC_ISRB.TXFFRDY and I2SMCC_ISRB.RXFFRDY must be used
9 instead.
10
11 Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
12 Link: https://lore.kernel.org/r/20210301170905.835091-7-codrin.ciubotariu@microchip.com
13 Signed-off-by: Mark Brown <broonie@kernel.org>
14 ---
15 sound/soc/atmel/mchp-i2s-mcc.c | 76 +++++++++++++++++++++++++---------
16 1 file changed, 56 insertions(+), 20 deletions(-)
17
18 --- a/sound/soc/atmel/mchp-i2s-mcc.c
19 +++ b/sound/soc/atmel/mchp-i2s-mcc.c
20 @@ -176,7 +176,7 @@
21 */
22 #define MCHP_I2SMCC_MRB_CRAMODE_REGULAR (1 << 0)
23
24 -#define MCHP_I2SMCC_MRB_FIFOEN BIT(1)
25 +#define MCHP_I2SMCC_MRB_FIFOEN BIT(4)
26
27 #define MCHP_I2SMCC_MRB_DMACHUNK_MASK GENMASK(9, 8)
28 #define MCHP_I2SMCC_MRB_DMACHUNK(no_words) \
29 @@ -230,6 +230,7 @@ static const struct regmap_config mchp_i
30
31 struct mchp_i2s_mcc_soc_data {
32 unsigned int data_pin_pair_num;
33 + bool has_fifo;
34 };
35
36 struct mchp_i2s_mcc_dev {
37 @@ -257,7 +258,7 @@ struct mchp_i2s_mcc_dev {
38 static irqreturn_t mchp_i2s_mcc_interrupt(int irq, void *dev_id)
39 {
40 struct mchp_i2s_mcc_dev *dev = dev_id;
41 - u32 sra, imra, srb, imrb, pendinga, pendingb, idra = 0;
42 + u32 sra, imra, srb, imrb, pendinga, pendingb, idra = 0, idrb = 0;
43 irqreturn_t ret = IRQ_NONE;
44
45 regmap_read(dev->regmap, MCHP_I2SMCC_IMRA, &imra);
46 @@ -275,24 +276,36 @@ static irqreturn_t mchp_i2s_mcc_interrup
47 * Tx/Rx ready interrupts are enabled when stopping only, to assure
48 * availability and to disable clocks if necessary
49 */
50 - idra |= pendinga & (MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels) |
51 - MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
52 - if (idra)
53 + if (dev->soc->has_fifo) {
54 + idrb |= pendingb & (MCHP_I2SMCC_INT_TXFFRDY |
55 + MCHP_I2SMCC_INT_RXFFRDY);
56 + } else {
57 + idra |= pendinga & (MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels) |
58 + MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
59 + }
60 + if (idra || idrb)
61 ret = IRQ_HANDLED;
62
63 - if ((imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) &&
64 - (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) ==
65 - (idra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels))) {
66 + if ((!dev->soc->has_fifo &&
67 + (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) &&
68 + (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) ==
69 + (idra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels))) ||
70 + (dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_TXFFRDY)) {
71 dev->tx_rdy = 1;
72 wake_up_interruptible(&dev->wq_txrdy);
73 }
74 - if ((imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) &&
75 - (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) ==
76 - (idra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels))) {
77 + if ((!dev->soc->has_fifo &&
78 + (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) &&
79 + (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) ==
80 + (idra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels))) ||
81 + (dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_RXFFRDY)) {
82 dev->rx_rdy = 1;
83 wake_up_interruptible(&dev->wq_rxrdy);
84 }
85 - regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra);
86 + if (dev->soc->has_fifo)
87 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRB, idrb);
88 + else
89 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra);
90
91 return ret;
92 }
93 @@ -664,6 +677,10 @@ static int mchp_i2s_mcc_hw_params(struct
94 }
95 }
96
97 + /* enable FIFO if available */
98 + if (dev->soc->has_fifo)
99 + mrb |= MCHP_I2SMCC_MRB_FIFOEN;
100 +
101 /*
102 * If we are already running, the wanted setup must be
103 * the same with the one that's currently ongoing
104 @@ -726,8 +743,13 @@ static int mchp_i2s_mcc_hw_free(struct s
105 if (err == 0) {
106 dev_warn_once(dev->dev,
107 "Timeout waiting for Tx ready\n");
108 - regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
109 - MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels));
110 + if (dev->soc->has_fifo)
111 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRB,
112 + MCHP_I2SMCC_INT_TXFFRDY);
113 + else
114 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
115 + MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels));
116 +
117 dev->tx_rdy = 1;
118 }
119 } else {
120 @@ -737,8 +759,12 @@ static int mchp_i2s_mcc_hw_free(struct s
121 if (err == 0) {
122 dev_warn_once(dev->dev,
123 "Timeout waiting for Rx ready\n");
124 - regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
125 - MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
126 + if (dev->soc->has_fifo)
127 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRB,
128 + MCHP_I2SMCC_INT_RXFFRDY);
129 + else
130 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
131 + MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
132 dev->rx_rdy = 1;
133 }
134 }
135 @@ -765,7 +791,7 @@ static int mchp_i2s_mcc_trigger(struct s
136 struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai);
137 bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
138 u32 cr = 0;
139 - u32 iera = 0;
140 + u32 iera = 0, ierb = 0;
141 u32 sr;
142 int err;
143
144 @@ -789,7 +815,10 @@ static int mchp_i2s_mcc_trigger(struct s
145 * Enable Tx Ready interrupts on all channels
146 * to assure all data is sent
147 */
148 - iera = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels);
149 + if (dev->soc->has_fifo)
150 + ierb = MCHP_I2SMCC_INT_TXFFRDY;
151 + else
152 + iera = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels);
153 } else if (!is_playback && (sr & MCHP_I2SMCC_SR_RXEN)) {
154 cr = MCHP_I2SMCC_CR_RXDIS;
155 dev->rx_rdy = 0;
156 @@ -797,7 +826,10 @@ static int mchp_i2s_mcc_trigger(struct s
157 * Enable Rx Ready interrupts on all channels
158 * to assure all data is received
159 */
160 - iera = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels);
161 + if (dev->soc->has_fifo)
162 + ierb = MCHP_I2SMCC_INT_RXFFRDY;
163 + else
164 + iera = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels);
165 }
166 break;
167 default:
168 @@ -815,7 +847,10 @@ static int mchp_i2s_mcc_trigger(struct s
169 }
170 }
171
172 - regmap_write(dev->regmap, MCHP_I2SMCC_IERA, iera);
173 + if (dev->soc->has_fifo)
174 + regmap_write(dev->regmap, MCHP_I2SMCC_IERB, ierb);
175 + else
176 + regmap_write(dev->regmap, MCHP_I2SMCC_IERA, iera);
177 regmap_write(dev->regmap, MCHP_I2SMCC_CR, cr);
178
179 return 0;
180 @@ -903,6 +938,7 @@ static struct mchp_i2s_mcc_soc_data mchp
181
182 static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sama7g5 = {
183 .data_pin_pair_num = 4,
184 + .has_fifo = true,
185 };
186
187 static const struct of_device_id mchp_i2s_mcc_dt_ids[] = {