]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/5.0.15/asoc-stm32-sai-fix-master-clock-management.patch
Linux 5.0.15
[thirdparty/kernel/stable-queue.git] / releases / 5.0.15 / asoc-stm32-sai-fix-master-clock-management.patch
1 From fc451a2b34464376802a2e2da2caa695e0e21de3 Mon Sep 17 00:00:00 2001
2 From: Olivier Moysan <olivier.moysan@st.com>
3 Date: Wed, 10 Apr 2019 10:08:36 +0200
4 Subject: ASoC: stm32: sai: fix master clock management
5
6 [ Upstream commit e37c2deafe7058cf7989c4c47bbf1140cc867d89 ]
7
8 When master clock is used, master clock rate is set exclusively.
9 Parent clocks of master clock cannot be changed after a call to
10 clk_set_rate_exclusive(). So the parent clock of SAI kernel clock
11 must be set before.
12 Ensure also that exclusive rate operations are balanced
13 in STM32 SAI driver.
14
15 Signed-off-by: Olivier Moysan <olivier.moysan@st.com>
16 Signed-off-by: Mark Brown <broonie@kernel.org>
17 Signed-off-by: Sasha Levin <sashal@kernel.org>
18 ---
19 sound/soc/stm/stm32_sai_sub.c | 64 +++++++++++++++++++++++++----------
20 1 file changed, 47 insertions(+), 17 deletions(-)
21
22 diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
23 index bc69e68191ad1..1cf9df4b6f11c 100644
24 --- a/sound/soc/stm/stm32_sai_sub.c
25 +++ b/sound/soc/stm/stm32_sai_sub.c
26 @@ -70,6 +70,7 @@
27 #define SAI_IEC60958_STATUS_BYTES 24
28
29 #define SAI_MCLK_NAME_LEN 32
30 +#define SAI_RATE_11K 11025
31
32 /**
33 * struct stm32_sai_sub_data - private data of SAI sub block (block A or B)
34 @@ -309,6 +310,25 @@ static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai,
35 return ret;
36 }
37
38 +static int stm32_sai_set_parent_clock(struct stm32_sai_sub_data *sai,
39 + unsigned int rate)
40 +{
41 + struct platform_device *pdev = sai->pdev;
42 + struct clk *parent_clk = sai->pdata->clk_x8k;
43 + int ret;
44 +
45 + if (!(rate % SAI_RATE_11K))
46 + parent_clk = sai->pdata->clk_x11k;
47 +
48 + ret = clk_set_parent(sai->sai_ck, parent_clk);
49 + if (ret)
50 + dev_err(&pdev->dev, " Error %d setting sai_ck parent clock. %s",
51 + ret, ret == -EBUSY ?
52 + "Active stream rates conflict\n" : "\n");
53 +
54 + return ret;
55 +}
56 +
57 static long stm32_sai_mclk_round_rate(struct clk_hw *hw, unsigned long rate,
58 unsigned long *prate)
59 {
60 @@ -490,25 +510,29 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai,
61 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
62 int ret;
63
64 - if (dir == SND_SOC_CLOCK_OUT) {
65 + if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) {
66 ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
67 SAI_XCR1_NODIV,
68 (unsigned int)~SAI_XCR1_NODIV);
69 if (ret < 0)
70 return ret;
71
72 - dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq);
73 - sai->mclk_rate = freq;
74 + /* If master clock is used, set parent clock now */
75 + ret = stm32_sai_set_parent_clock(sai, freq);
76 + if (ret)
77 + return ret;
78
79 - if (sai->sai_mclk) {
80 - ret = clk_set_rate_exclusive(sai->sai_mclk,
81 - sai->mclk_rate);
82 - if (ret) {
83 - dev_err(cpu_dai->dev,
84 - "Could not set mclk rate\n");
85 - return ret;
86 - }
87 + ret = clk_set_rate_exclusive(sai->sai_mclk, freq);
88 + if (ret) {
89 + dev_err(cpu_dai->dev,
90 + ret == -EBUSY ?
91 + "Active streams have incompatible rates" :
92 + "Could not set mclk rate\n");
93 + return ret;
94 }
95 +
96 + dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq);
97 + sai->mclk_rate = freq;
98 }
99
100 return 0;
101 @@ -916,11 +940,13 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
102 int cr1, mask, div = 0;
103 int sai_clk_rate, mclk_ratio, den;
104 unsigned int rate = params_rate(params);
105 + int ret;
106
107 - if (!(rate % 11025))
108 - clk_set_parent(sai->sai_ck, sai->pdata->clk_x11k);
109 - else
110 - clk_set_parent(sai->sai_ck, sai->pdata->clk_x8k);
111 + if (!sai->sai_mclk) {
112 + ret = stm32_sai_set_parent_clock(sai, rate);
113 + if (ret)
114 + return ret;
115 + }
116 sai_clk_rate = clk_get_rate(sai->sai_ck);
117
118 if (STM_SAI_IS_F4(sai->pdata)) {
119 @@ -1075,9 +1101,13 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream,
120 regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_NODIV,
121 SAI_XCR1_NODIV);
122
123 - clk_disable_unprepare(sai->sai_ck);
124 + /* Release mclk rate only if rate was actually set */
125 + if (sai->mclk_rate) {
126 + clk_rate_exclusive_put(sai->sai_mclk);
127 + sai->mclk_rate = 0;
128 + }
129
130 - clk_rate_exclusive_put(sai->sai_mclk);
131 + clk_disable_unprepare(sai->sai_ck);
132
133 spin_lock_irqsave(&sai->irq_lock, flags);
134 sai->substream = NULL;
135 --
136 2.20.1
137