diff options
author | Mark Brown <broonie@kernel.org> | 2016-02-08 11:44:12 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-02-08 11:44:12 -0500 |
commit | 98ab7a02046dd239f3f2eb923de0ce117dc29e15 (patch) | |
tree | 0f642d84f3b402d5325b657d68e18d423f6d571e | |
parent | 6f08cbdaac5a3050ea1898aef8ce326030fd1117 (diff) | |
parent | 38c079e230f25969e7ce3501fa967b003a2abc39 (diff) |
Merge branch 'fix/intel' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-intel
-rw-r--r-- | sound/soc/intel/atom/sst-mfld-platform-pcm.c | 1 | ||||
-rw-r--r-- | sound/soc/intel/boards/skl_rt286.c | 5 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-messages.c | 6 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-pcm.c | 1 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-topology.c | 75 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl.c | 2 |
6 files changed, 61 insertions, 29 deletions
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index 55c33dc76ce4..52ed434cbca6 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c | |||
@@ -528,6 +528,7 @@ static struct snd_soc_dai_driver sst_platform_dai[] = { | |||
528 | .ops = &sst_compr_dai_ops, | 528 | .ops = &sst_compr_dai_ops, |
529 | .playback = { | 529 | .playback = { |
530 | .stream_name = "Compress Playback", | 530 | .stream_name = "Compress Playback", |
531 | .channels_min = 1, | ||
531 | }, | 532 | }, |
532 | }, | 533 | }, |
533 | /* BE CPU Dais */ | 534 | /* BE CPU Dais */ |
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c index 7396ddb427d8..2cbcbe412661 100644 --- a/sound/soc/intel/boards/skl_rt286.c +++ b/sound/soc/intel/boards/skl_rt286.c | |||
@@ -212,7 +212,10 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, | |||
212 | { | 212 | { |
213 | struct snd_interval *channels = hw_param_interval(params, | 213 | struct snd_interval *channels = hw_param_interval(params, |
214 | SNDRV_PCM_HW_PARAM_CHANNELS); | 214 | SNDRV_PCM_HW_PARAM_CHANNELS); |
215 | channels->min = channels->max = 4; | 215 | if (params_channels(params) == 2) |
216 | channels->min = channels->max = 2; | ||
217 | else | ||
218 | channels->min = channels->max = 4; | ||
216 | 219 | ||
217 | return 0; | 220 | return 0; |
218 | } | 221 | } |
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index de6dac496a0d..4629372d7c8e 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c | |||
@@ -688,14 +688,14 @@ int skl_unbind_modules(struct skl_sst *ctx, | |||
688 | /* get src queue index */ | 688 | /* get src queue index */ |
689 | src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); | 689 | src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); |
690 | if (src_index < 0) | 690 | if (src_index < 0) |
691 | return -EINVAL; | 691 | return 0; |
692 | 692 | ||
693 | msg.src_queue = src_index; | 693 | msg.src_queue = src_index; |
694 | 694 | ||
695 | /* get dst queue index */ | 695 | /* get dst queue index */ |
696 | dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max); | 696 | dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max); |
697 | if (dst_index < 0) | 697 | if (dst_index < 0) |
698 | return -EINVAL; | 698 | return 0; |
699 | 699 | ||
700 | msg.dst_queue = dst_index; | 700 | msg.dst_queue = dst_index; |
701 | 701 | ||
@@ -747,7 +747,7 @@ int skl_bind_modules(struct skl_sst *ctx, | |||
747 | 747 | ||
748 | skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); | 748 | skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); |
749 | 749 | ||
750 | if (src_mcfg->m_state < SKL_MODULE_INIT_DONE && | 750 | if (src_mcfg->m_state < SKL_MODULE_INIT_DONE || |
751 | dst_mcfg->m_state < SKL_MODULE_INIT_DONE) | 751 | dst_mcfg->m_state < SKL_MODULE_INIT_DONE) |
752 | return 0; | 752 | return 0; |
753 | 753 | ||
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index f3553258091a..b6e6b61d10ec 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c | |||
@@ -863,6 +863,7 @@ static int skl_get_delay_from_lpib(struct hdac_ext_bus *ebus, | |||
863 | else | 863 | else |
864 | delay += hstream->bufsize; | 864 | delay += hstream->bufsize; |
865 | } | 865 | } |
866 | delay = (hstream->bufsize == delay) ? 0 : delay; | ||
866 | 867 | ||
867 | if (delay >= hstream->period_bytes) { | 868 | if (delay >= hstream->period_bytes) { |
868 | dev_info(bus->dev, | 869 | dev_info(bus->dev, |
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 4624556f486d..a294fee431f0 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c | |||
@@ -54,12 +54,9 @@ static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w) | |||
54 | 54 | ||
55 | /* | 55 | /* |
56 | * Each pipelines needs memory to be allocated. Check if we have free memory | 56 | * Each pipelines needs memory to be allocated. Check if we have free memory |
57 | * from available pool. Then only add this to pool | 57 | * from available pool. |
58 | * This is freed when pipe is deleted | ||
59 | * Note: DSP does actual memory management we only keep track for complete | ||
60 | * pool | ||
61 | */ | 58 | */ |
62 | static bool skl_tplg_alloc_pipe_mem(struct skl *skl, | 59 | static bool skl_is_pipe_mem_avail(struct skl *skl, |
63 | struct skl_module_cfg *mconfig) | 60 | struct skl_module_cfg *mconfig) |
64 | { | 61 | { |
65 | struct skl_sst *ctx = skl->skl_sst; | 62 | struct skl_sst *ctx = skl->skl_sst; |
@@ -74,10 +71,20 @@ static bool skl_tplg_alloc_pipe_mem(struct skl *skl, | |||
74 | "exceeds ppl memory available %d mem %d\n", | 71 | "exceeds ppl memory available %d mem %d\n", |
75 | skl->resource.max_mem, skl->resource.mem); | 72 | skl->resource.max_mem, skl->resource.mem); |
76 | return false; | 73 | return false; |
74 | } else { | ||
75 | return true; | ||
77 | } | 76 | } |
77 | } | ||
78 | 78 | ||
79 | /* | ||
80 | * Add the mem to the mem pool. This is freed when pipe is deleted. | ||
81 | * Note: DSP does actual memory management we only keep track for complete | ||
82 | * pool | ||
83 | */ | ||
84 | static void skl_tplg_alloc_pipe_mem(struct skl *skl, | ||
85 | struct skl_module_cfg *mconfig) | ||
86 | { | ||
79 | skl->resource.mem += mconfig->pipe->memory_pages; | 87 | skl->resource.mem += mconfig->pipe->memory_pages; |
80 | return true; | ||
81 | } | 88 | } |
82 | 89 | ||
83 | /* | 90 | /* |
@@ -85,10 +92,10 @@ static bool skl_tplg_alloc_pipe_mem(struct skl *skl, | |||
85 | * quantified in MCPS (Million Clocks Per Second) required for module/pipe | 92 | * quantified in MCPS (Million Clocks Per Second) required for module/pipe |
86 | * | 93 | * |
87 | * Each pipelines needs mcps to be allocated. Check if we have mcps for this | 94 | * Each pipelines needs mcps to be allocated. Check if we have mcps for this |
88 | * pipe. This adds the mcps to driver counter | 95 | * pipe. |
89 | * This is removed on pipeline delete | ||
90 | */ | 96 | */ |
91 | static bool skl_tplg_alloc_pipe_mcps(struct skl *skl, | 97 | |
98 | static bool skl_is_pipe_mcps_avail(struct skl *skl, | ||
92 | struct skl_module_cfg *mconfig) | 99 | struct skl_module_cfg *mconfig) |
93 | { | 100 | { |
94 | struct skl_sst *ctx = skl->skl_sst; | 101 | struct skl_sst *ctx = skl->skl_sst; |
@@ -98,13 +105,18 @@ static bool skl_tplg_alloc_pipe_mcps(struct skl *skl, | |||
98 | "%s: module_id %d instance %d\n", __func__, | 105 | "%s: module_id %d instance %d\n", __func__, |
99 | mconfig->id.module_id, mconfig->id.instance_id); | 106 | mconfig->id.module_id, mconfig->id.instance_id); |
100 | dev_err(ctx->dev, | 107 | dev_err(ctx->dev, |
101 | "exceeds ppl memory available %d > mem %d\n", | 108 | "exceeds ppl mcps available %d > mem %d\n", |
102 | skl->resource.max_mcps, skl->resource.mcps); | 109 | skl->resource.max_mcps, skl->resource.mcps); |
103 | return false; | 110 | return false; |
111 | } else { | ||
112 | return true; | ||
104 | } | 113 | } |
114 | } | ||
105 | 115 | ||
116 | static void skl_tplg_alloc_pipe_mcps(struct skl *skl, | ||
117 | struct skl_module_cfg *mconfig) | ||
118 | { | ||
106 | skl->resource.mcps += mconfig->mcps; | 119 | skl->resource.mcps += mconfig->mcps; |
107 | return true; | ||
108 | } | 120 | } |
109 | 121 | ||
110 | /* | 122 | /* |
@@ -411,7 +423,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) | |||
411 | mconfig = w->priv; | 423 | mconfig = w->priv; |
412 | 424 | ||
413 | /* check resource available */ | 425 | /* check resource available */ |
414 | if (!skl_tplg_alloc_pipe_mcps(skl, mconfig)) | 426 | if (!skl_is_pipe_mcps_avail(skl, mconfig)) |
415 | return -ENOMEM; | 427 | return -ENOMEM; |
416 | 428 | ||
417 | if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) { | 429 | if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) { |
@@ -435,6 +447,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) | |||
435 | ret = skl_tplg_set_module_params(w, ctx); | 447 | ret = skl_tplg_set_module_params(w, ctx); |
436 | if (ret < 0) | 448 | if (ret < 0) |
437 | return ret; | 449 | return ret; |
450 | skl_tplg_alloc_pipe_mcps(skl, mconfig); | ||
438 | } | 451 | } |
439 | 452 | ||
440 | return 0; | 453 | return 0; |
@@ -477,10 +490,10 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, | |||
477 | struct skl_sst *ctx = skl->skl_sst; | 490 | struct skl_sst *ctx = skl->skl_sst; |
478 | 491 | ||
479 | /* check resource available */ | 492 | /* check resource available */ |
480 | if (!skl_tplg_alloc_pipe_mcps(skl, mconfig)) | 493 | if (!skl_is_pipe_mcps_avail(skl, mconfig)) |
481 | return -EBUSY; | 494 | return -EBUSY; |
482 | 495 | ||
483 | if (!skl_tplg_alloc_pipe_mem(skl, mconfig)) | 496 | if (!skl_is_pipe_mem_avail(skl, mconfig)) |
484 | return -ENOMEM; | 497 | return -ENOMEM; |
485 | 498 | ||
486 | /* | 499 | /* |
@@ -526,11 +539,15 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, | |||
526 | src_module = dst_module; | 539 | src_module = dst_module; |
527 | } | 540 | } |
528 | 541 | ||
542 | skl_tplg_alloc_pipe_mem(skl, mconfig); | ||
543 | skl_tplg_alloc_pipe_mcps(skl, mconfig); | ||
544 | |||
529 | return 0; | 545 | return 0; |
530 | } | 546 | } |
531 | 547 | ||
532 | static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, | 548 | static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, |
533 | struct skl *skl, | 549 | struct skl *skl, |
550 | struct snd_soc_dapm_widget *src_w, | ||
534 | struct skl_module_cfg *src_mconfig) | 551 | struct skl_module_cfg *src_mconfig) |
535 | { | 552 | { |
536 | struct snd_soc_dapm_path *p; | 553 | struct snd_soc_dapm_path *p; |
@@ -547,6 +564,10 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, | |||
547 | dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name); | 564 | dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name); |
548 | 565 | ||
549 | next_sink = p->sink; | 566 | next_sink = p->sink; |
567 | |||
568 | if (!is_skl_dsp_widget_type(p->sink)) | ||
569 | return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig); | ||
570 | |||
550 | /* | 571 | /* |
551 | * here we will check widgets in sink pipelines, so that | 572 | * here we will check widgets in sink pipelines, so that |
552 | * can be any widgets type and we are only interested if | 573 | * can be any widgets type and we are only interested if |
@@ -576,7 +597,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, | |||
576 | } | 597 | } |
577 | 598 | ||
578 | if (!sink) | 599 | if (!sink) |
579 | return skl_tplg_bind_sinks(next_sink, skl, src_mconfig); | 600 | return skl_tplg_bind_sinks(next_sink, skl, src_w, src_mconfig); |
580 | 601 | ||
581 | return 0; | 602 | return 0; |
582 | } | 603 | } |
@@ -605,7 +626,7 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, | |||
605 | * if sink is not started, start sink pipe first, then start | 626 | * if sink is not started, start sink pipe first, then start |
606 | * this pipe | 627 | * this pipe |
607 | */ | 628 | */ |
608 | ret = skl_tplg_bind_sinks(w, skl, src_mconfig); | 629 | ret = skl_tplg_bind_sinks(w, skl, w, src_mconfig); |
609 | if (ret) | 630 | if (ret) |
610 | return ret; | 631 | return ret; |
611 | 632 | ||
@@ -773,10 +794,7 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, | |||
773 | continue; | 794 | continue; |
774 | } | 795 | } |
775 | 796 | ||
776 | ret = skl_unbind_modules(ctx, src_module, dst_module); | 797 | skl_unbind_modules(ctx, src_module, dst_module); |
777 | if (ret < 0) | ||
778 | return ret; | ||
779 | |||
780 | src_module = dst_module; | 798 | src_module = dst_module; |
781 | } | 799 | } |
782 | 800 | ||
@@ -814,9 +832,6 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, | |||
814 | * This is a connecter and if path is found that means | 832 | * This is a connecter and if path is found that means |
815 | * unbind between source and sink has not happened yet | 833 | * unbind between source and sink has not happened yet |
816 | */ | 834 | */ |
817 | ret = skl_stop_pipe(ctx, sink_mconfig->pipe); | ||
818 | if (ret < 0) | ||
819 | return ret; | ||
820 | ret = skl_unbind_modules(ctx, src_mconfig, | 835 | ret = skl_unbind_modules(ctx, src_mconfig, |
821 | sink_mconfig); | 836 | sink_mconfig); |
822 | } | 837 | } |
@@ -842,6 +857,12 @@ static int skl_tplg_vmixer_event(struct snd_soc_dapm_widget *w, | |||
842 | case SND_SOC_DAPM_PRE_PMU: | 857 | case SND_SOC_DAPM_PRE_PMU: |
843 | return skl_tplg_mixer_dapm_pre_pmu_event(w, skl); | 858 | return skl_tplg_mixer_dapm_pre_pmu_event(w, skl); |
844 | 859 | ||
860 | case SND_SOC_DAPM_POST_PMU: | ||
861 | return skl_tplg_mixer_dapm_post_pmu_event(w, skl); | ||
862 | |||
863 | case SND_SOC_DAPM_PRE_PMD: | ||
864 | return skl_tplg_mixer_dapm_pre_pmd_event(w, skl); | ||
865 | |||
845 | case SND_SOC_DAPM_POST_PMD: | 866 | case SND_SOC_DAPM_POST_PMD: |
846 | return skl_tplg_mixer_dapm_post_pmd_event(w, skl); | 867 | return skl_tplg_mixer_dapm_post_pmd_event(w, skl); |
847 | } | 868 | } |
@@ -916,6 +937,13 @@ static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol, | |||
916 | skl_get_module_params(skl->skl_sst, (u32 *)bc->params, | 937 | skl_get_module_params(skl->skl_sst, (u32 *)bc->params, |
917 | bc->max, bc->param_id, mconfig); | 938 | bc->max, bc->param_id, mconfig); |
918 | 939 | ||
940 | /* decrement size for TLV header */ | ||
941 | size -= 2 * sizeof(u32); | ||
942 | |||
943 | /* check size as we don't want to send kernel data */ | ||
944 | if (size > bc->max) | ||
945 | size = bc->max; | ||
946 | |||
919 | if (bc->params) { | 947 | if (bc->params) { |
920 | if (copy_to_user(data, &bc->param_id, sizeof(u32))) | 948 | if (copy_to_user(data, &bc->param_id, sizeof(u32))) |
921 | return -EFAULT; | 949 | return -EFAULT; |
@@ -1510,6 +1538,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus) | |||
1510 | &skl_tplg_ops, fw, 0); | 1538 | &skl_tplg_ops, fw, 0); |
1511 | if (ret < 0) { | 1539 | if (ret < 0) { |
1512 | dev_err(bus->dev, "tplg component load failed%d\n", ret); | 1540 | dev_err(bus->dev, "tplg component load failed%d\n", ret); |
1541 | release_firmware(fw); | ||
1513 | return -EINVAL; | 1542 | return -EINVAL; |
1514 | } | 1543 | } |
1515 | 1544 | ||
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 443a15de94b5..092705e73db4 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c | |||
@@ -614,8 +614,6 @@ static int skl_probe(struct pci_dev *pci, | |||
614 | goto out_unregister; | 614 | goto out_unregister; |
615 | 615 | ||
616 | /*configure PM */ | 616 | /*configure PM */ |
617 | pm_runtime_set_autosuspend_delay(bus->dev, SKL_SUSPEND_DELAY); | ||
618 | pm_runtime_use_autosuspend(bus->dev); | ||
619 | pm_runtime_put_noidle(bus->dev); | 617 | pm_runtime_put_noidle(bus->dev); |
620 | pm_runtime_allow(bus->dev); | 618 | pm_runtime_allow(bus->dev); |
621 | 619 | ||