aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2017-12-20 10:43:03 -0500
committerMark Brown <broonie@kernel.org>2017-12-20 10:43:03 -0500
commit54dbb868afa50c4bcbf06c6e531966ba374a41d5 (patch)
tree6a731c8cce422961cde5d98d70d371cfce5bf5e1
parent6331d77e056fa058109df43c1f2a89859cd1d128 (diff)
parentd5aa24825da5711f8cb829f873160ddf1a29b19c (diff)
Merge remote-tracking branch 'asoc/fix/rcar' into asoc-linus
-rw-r--r--sound/soc/sh/rcar/adg.c6
-rw-r--r--sound/soc/sh/rcar/core.c4
-rw-r--r--sound/soc/sh/rcar/dma.c86
-rw-r--r--sound/soc/sh/rcar/ssi.c16
-rw-r--r--sound/soc/sh/rcar/ssiu.c5
5 files changed, 25 insertions, 92 deletions
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 8ddb08714faa..4672688cac32 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -222,7 +222,7 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *cmd_mod,
222 NULL, &val, NULL); 222 NULL, &val, NULL);
223 223
224 val = val << shift; 224 val = val << shift;
225 mask = 0xffff << shift; 225 mask = 0x0f1f << shift;
226 226
227 rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val); 227 rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val);
228 228
@@ -250,7 +250,7 @@ int rsnd_adg_set_src_timesel_gen2(struct rsnd_mod *src_mod,
250 250
251 in = in << shift; 251 in = in << shift;
252 out = out << shift; 252 out = out << shift;
253 mask = 0xffff << shift; 253 mask = 0x0f1f << shift;
254 254
255 switch (id / 2) { 255 switch (id / 2) {
256 case 0: 256 case 0:
@@ -380,7 +380,7 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
380 ckr = 0x80000000; 380 ckr = 0x80000000;
381 } 381 }
382 382
383 rsnd_mod_bset(adg_mod, BRGCKR, 0x80FF0000, adg->ckr | ckr); 383 rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr | ckr);
384 rsnd_mod_write(adg_mod, BRRA, adg->rbga); 384 rsnd_mod_write(adg_mod, BRRA, adg->rbga);
385 rsnd_mod_write(adg_mod, BRRB, adg->rbgb); 385 rsnd_mod_write(adg_mod, BRRB, adg->rbgb);
386 386
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index c70eb2097816..f12a88a21dfa 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1332,8 +1332,8 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
1332 1332
1333 return snd_pcm_lib_preallocate_pages_for_all( 1333 return snd_pcm_lib_preallocate_pages_for_all(
1334 rtd->pcm, 1334 rtd->pcm,
1335 SNDRV_DMA_TYPE_CONTINUOUS, 1335 SNDRV_DMA_TYPE_DEV,
1336 snd_dma_continuous_data(GFP_KERNEL), 1336 rtd->card->snd_card->dev,
1337 PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); 1337 PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
1338} 1338}
1339 1339
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index fd557abfe390..4d750bdf8e24 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -26,10 +26,7 @@
26struct rsnd_dmaen { 26struct rsnd_dmaen {
27 struct dma_chan *chan; 27 struct dma_chan *chan;
28 dma_cookie_t cookie; 28 dma_cookie_t cookie;
29 dma_addr_t dma_buf;
30 unsigned int dma_len; 29 unsigned int dma_len;
31 unsigned int dma_period;
32 unsigned int dma_cnt;
33}; 30};
34 31
35struct rsnd_dmapp { 32struct rsnd_dmapp {
@@ -71,38 +68,10 @@ static struct rsnd_mod mem = {
71/* 68/*
72 * Audio DMAC 69 * Audio DMAC
73 */ 70 */
74#define rsnd_dmaen_sync(dmaen, io, i) __rsnd_dmaen_sync(dmaen, io, i, 1)
75#define rsnd_dmaen_unsync(dmaen, io, i) __rsnd_dmaen_sync(dmaen, io, i, 0)
76static void __rsnd_dmaen_sync(struct rsnd_dmaen *dmaen, struct rsnd_dai_stream *io,
77 int i, int sync)
78{
79 struct device *dev = dmaen->chan->device->dev;
80 enum dma_data_direction dir;
81 int is_play = rsnd_io_is_play(io);
82 dma_addr_t buf;
83 int len, max;
84 size_t period;
85
86 len = dmaen->dma_len;
87 period = dmaen->dma_period;
88 max = len / period;
89 i = i % max;
90 buf = dmaen->dma_buf + (period * i);
91
92 dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
93
94 if (sync)
95 dma_sync_single_for_device(dev, buf, period, dir);
96 else
97 dma_sync_single_for_cpu(dev, buf, period, dir);
98}
99
100static void __rsnd_dmaen_complete(struct rsnd_mod *mod, 71static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
101 struct rsnd_dai_stream *io) 72 struct rsnd_dai_stream *io)
102{ 73{
103 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 74 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
104 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
105 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
106 bool elapsed = false; 75 bool elapsed = false;
107 unsigned long flags; 76 unsigned long flags;
108 77
@@ -115,22 +84,9 @@ static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
115 */ 84 */
116 spin_lock_irqsave(&priv->lock, flags); 85 spin_lock_irqsave(&priv->lock, flags);
117 86
118 if (rsnd_io_is_working(io)) { 87 if (rsnd_io_is_working(io))
119 rsnd_dmaen_unsync(dmaen, io, dmaen->dma_cnt);
120
121 /*
122 * Next period is already started.
123 * Let's sync Next Next period
124 * see
125 * rsnd_dmaen_start()
126 */
127 rsnd_dmaen_sync(dmaen, io, dmaen->dma_cnt + 2);
128
129 elapsed = true; 88 elapsed = true;
130 89
131 dmaen->dma_cnt++;
132 }
133
134 spin_unlock_irqrestore(&priv->lock, flags); 90 spin_unlock_irqrestore(&priv->lock, flags);
135 91
136 if (elapsed) 92 if (elapsed)
@@ -165,14 +121,8 @@ static int rsnd_dmaen_stop(struct rsnd_mod *mod,
165 struct rsnd_dma *dma = rsnd_mod_to_dma(mod); 121 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
166 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); 122 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
167 123
168 if (dmaen->chan) { 124 if (dmaen->chan)
169 int is_play = rsnd_io_is_play(io);
170
171 dmaengine_terminate_all(dmaen->chan); 125 dmaengine_terminate_all(dmaen->chan);
172 dma_unmap_single(dmaen->chan->device->dev,
173 dmaen->dma_buf, dmaen->dma_len,
174 is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
175 }
176 126
177 return 0; 127 return 0;
178} 128}
@@ -237,11 +187,7 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
237 struct device *dev = rsnd_priv_to_dev(priv); 187 struct device *dev = rsnd_priv_to_dev(priv);
238 struct dma_async_tx_descriptor *desc; 188 struct dma_async_tx_descriptor *desc;
239 struct dma_slave_config cfg = {}; 189 struct dma_slave_config cfg = {};
240 dma_addr_t buf;
241 size_t len;
242 size_t period;
243 int is_play = rsnd_io_is_play(io); 190 int is_play = rsnd_io_is_play(io);
244 int i;
245 int ret; 191 int ret;
246 192
247 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; 193 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
@@ -258,19 +204,10 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
258 if (ret < 0) 204 if (ret < 0)
259 return ret; 205 return ret;
260 206
261 len = snd_pcm_lib_buffer_bytes(substream);
262 period = snd_pcm_lib_period_bytes(substream);
263 buf = dma_map_single(dmaen->chan->device->dev,
264 substream->runtime->dma_area,
265 len,
266 is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
267 if (dma_mapping_error(dmaen->chan->device->dev, buf)) {
268 dev_err(dev, "dma map failed\n");
269 return -EIO;
270 }
271
272 desc = dmaengine_prep_dma_cyclic(dmaen->chan, 207 desc = dmaengine_prep_dma_cyclic(dmaen->chan,
273 buf, len, period, 208 substream->runtime->dma_addr,
209 snd_pcm_lib_buffer_bytes(substream),
210 snd_pcm_lib_period_bytes(substream),
274 is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, 211 is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
275 DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 212 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
276 213
@@ -282,18 +219,7 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
282 desc->callback = rsnd_dmaen_complete; 219 desc->callback = rsnd_dmaen_complete;
283 desc->callback_param = rsnd_mod_get(dma); 220 desc->callback_param = rsnd_mod_get(dma);
284 221
285 dmaen->dma_buf = buf; 222 dmaen->dma_len = snd_pcm_lib_buffer_bytes(substream);
286 dmaen->dma_len = len;
287 dmaen->dma_period = period;
288 dmaen->dma_cnt = 0;
289
290 /*
291 * synchronize this and next period
292 * see
293 * __rsnd_dmaen_complete()
294 */
295 for (i = 0; i < 2; i++)
296 rsnd_dmaen_sync(dmaen, io, i);
297 223
298 dmaen->cookie = dmaengine_submit(desc); 224 dmaen->cookie = dmaengine_submit(desc);
299 if (dmaen->cookie < 0) { 225 if (dmaen->cookie < 0) {
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index fece1e5f582f..cbf3bf312d23 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -446,25 +446,29 @@ static bool rsnd_ssi_pointer_update(struct rsnd_mod *mod,
446 int byte) 446 int byte)
447{ 447{
448 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 448 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
449 bool ret = false;
450 int byte_pos;
449 451
450 ssi->byte_pos += byte; 452 byte_pos = ssi->byte_pos + byte;
451 453
452 if (ssi->byte_pos >= ssi->next_period_byte) { 454 if (byte_pos >= ssi->next_period_byte) {
453 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 455 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
454 456
455 ssi->period_pos++; 457 ssi->period_pos++;
456 ssi->next_period_byte += ssi->byte_per_period; 458 ssi->next_period_byte += ssi->byte_per_period;
457 459
458 if (ssi->period_pos >= runtime->periods) { 460 if (ssi->period_pos >= runtime->periods) {
459 ssi->byte_pos = 0; 461 byte_pos = 0;
460 ssi->period_pos = 0; 462 ssi->period_pos = 0;
461 ssi->next_period_byte = ssi->byte_per_period; 463 ssi->next_period_byte = ssi->byte_per_period;
462 } 464 }
463 465
464 return true; 466 ret = true;
465 } 467 }
466 468
467 return false; 469 WRITE_ONCE(ssi->byte_pos, byte_pos);
470
471 return ret;
468} 472}
469 473
470/* 474/*
@@ -838,7 +842,7 @@ static int rsnd_ssi_pointer(struct rsnd_mod *mod,
838 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 842 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
839 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 843 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
840 844
841 *pointer = bytes_to_frames(runtime, ssi->byte_pos); 845 *pointer = bytes_to_frames(runtime, READ_ONCE(ssi->byte_pos));
842 846
843 return 0; 847 return 0;
844} 848}
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index 4d948757d300..6ff8a36c2c82 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -125,6 +125,7 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
125{ 125{
126 int hdmi = rsnd_ssi_hdmi_port(io); 126 int hdmi = rsnd_ssi_hdmi_port(io);
127 int ret; 127 int ret;
128 u32 mode = 0;
128 129
129 ret = rsnd_ssiu_init(mod, io, priv); 130 ret = rsnd_ssiu_init(mod, io, priv);
130 if (ret < 0) 131 if (ret < 0)
@@ -136,9 +137,11 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
136 * see 137 * see
137 * rsnd_ssi_config_init() 138 * rsnd_ssi_config_init()
138 */ 139 */
139 rsnd_mod_write(mod, SSI_MODE, 0x1); 140 mode = 0x1;
140 } 141 }
141 142
143 rsnd_mod_write(mod, SSI_MODE, mode);
144
142 if (rsnd_ssi_use_busif(io)) { 145 if (rsnd_ssi_use_busif(io)) {
143 rsnd_mod_write(mod, SSI_BUSIF_ADINR, 146 rsnd_mod_write(mod, SSI_BUSIF_ADINR,
144 rsnd_get_adinr_bit(mod, io) | 147 rsnd_get_adinr_bit(mod, io) |