mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
ASoC: tegra-alt: Add APE power domain support
1. Add APE power domain support to xbar and adsp driver. 2. Also add runtime PM support in adsp audio driver to ensure APE PM domain works properly. 3. Add code in xbar system suspend callback to support calling of all xbar child driver system suspend. This is required to properly support APE PM domain. Bug 200039212 Change-Id: Ieb937b05e39d4e980872745e3b6580bca3eb6956 Signed-off-by: Sumit Bhattacharya <sumitb@nvidia.com> Reviewed-on: http://git-master/r/555433
This commit is contained in:
committed by
Sameer Pujar
parent
dbae79bb60
commit
8bd1b0a7ae
@@ -30,6 +30,8 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/tegra_pm_domains.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/firmware.h>
|
||||
@@ -1909,6 +1911,7 @@ static int tegra210_adsp_codec_probe(struct snd_soc_codec *codec)
|
||||
|
||||
static struct snd_soc_codec_driver tegra210_adsp_codec = {
|
||||
.probe = tegra210_adsp_codec_probe,
|
||||
.idle_bias_off = 1,
|
||||
};
|
||||
|
||||
static struct snd_soc_platform_driver tegra210_adsp_platform = {
|
||||
@@ -1947,6 +1950,15 @@ static int tegra210_adsp_audio_platform_probe(struct platform_device *pdev)
|
||||
pdev->dev.dma_mask = &tegra_dma_mask;
|
||||
pdev->dev.coherent_dma_mask = tegra_dma_mask;
|
||||
|
||||
tegra_ape_pd_add_device(&pdev->dev);
|
||||
pm_genpd_dev_need_save(&pdev->dev, true);
|
||||
pm_genpd_dev_need_restore(&pdev->dev, true);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
if (!pm_runtime_enabled(&pdev->dev))
|
||||
goto err_pm_disable;
|
||||
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
/* HACK : Should be handled through dma-engine */
|
||||
for (i = 0; i < TEGRA210_ADSP_ADMA_CHANNEL_COUNT; i++) {
|
||||
ret = tegra_agic_route_interrupt(
|
||||
@@ -1954,10 +1966,11 @@ static int tegra210_adsp_audio_platform_probe(struct platform_device *pdev)
|
||||
TEGRA_AGIC_ADSP);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to route INT to ADSP");
|
||||
return ret;
|
||||
goto err_pm_disable;
|
||||
}
|
||||
}
|
||||
/* HACK end */
|
||||
pm_runtime_put(&pdev->dev);
|
||||
|
||||
for (i = 0; i < TEGRA210_ADSP_VIRT_REG_MAX; i++)
|
||||
adsp->apps[i].reg = i;
|
||||
@@ -1971,7 +1984,7 @@ static int tegra210_adsp_audio_platform_probe(struct platform_device *pdev)
|
||||
ret = snd_soc_register_platform(&pdev->dev, &tegra210_adsp_platform);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Could not register platform: %d\n", ret);
|
||||
goto err;
|
||||
goto err_pm_disable;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_component(&pdev->dev, &tegra210_adsp_component,
|
||||
@@ -1994,12 +2007,16 @@ static int tegra210_adsp_audio_platform_probe(struct platform_device *pdev)
|
||||
|
||||
err_unregister_platform:
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
err:
|
||||
err_pm_disable:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
tegra_ape_pd_remove_device(&pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tegra210_adsp_audio_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
tegra_ape_pd_remove_device(&pdev->dev);
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/tegra_pm_domains.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <sound/soc.h>
|
||||
@@ -82,9 +83,16 @@ static int tegra210_xbar_runtime_resume(struct device *dev)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int tegra210_xbar_child_suspend(struct device *dev, void *data)
|
||||
{
|
||||
return platform_pm_suspend(dev);
|
||||
}
|
||||
|
||||
static int tegra210_xbar_suspend(struct device *dev)
|
||||
{
|
||||
regcache_mark_dirty(xbar->regmap);
|
||||
device_for_each_child(dev, NULL, tegra210_xbar_child_suspend);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -904,6 +912,10 @@ static int tegra210_xbar_probe(struct platform_device *pdev)
|
||||
}
|
||||
regcache_cache_only(xbar->regmap, true);
|
||||
|
||||
tegra_ape_pd_add_device(&pdev->dev);
|
||||
pm_genpd_dev_need_save(&pdev->dev, true);
|
||||
pm_genpd_dev_need_restore(&pdev->dev, true);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
if (!pm_runtime_enabled(&pdev->dev)) {
|
||||
ret = tegra210_xbar_runtime_resume(&pdev->dev);
|
||||
@@ -927,6 +939,7 @@ err_suspend:
|
||||
tegra210_xbar_runtime_suspend(&pdev->dev);
|
||||
err_pm_disable:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
tegra_ape_pd_remove_device(&pdev->dev);
|
||||
err_clk_set_parent:
|
||||
clk_set_parent(xbar->clk, parent_clk);
|
||||
err_clk_put_ape:
|
||||
@@ -947,6 +960,8 @@ static int tegra210_xbar_remove(struct platform_device *pdev)
|
||||
if (!pm_runtime_status_suspended(&pdev->dev))
|
||||
tegra210_xbar_runtime_suspend(&pdev->dev);
|
||||
|
||||
tegra_ape_pd_remove_device(&pdev->dev);
|
||||
|
||||
devm_clk_put(&pdev->dev, xbar->clk);
|
||||
clk_put(xbar->clk_parent);
|
||||
clk_put(xbar->clk_ape);
|
||||
|
||||
Reference in New Issue
Block a user