From d25d71e53f4e17218169765819ea60b14a93297d Mon Sep 17 00:00:00 2001 From: Prateek Patel Date: Tue, 14 Nov 2017 04:55:15 -0800 Subject: [PATCH] platform: tegra: adsp: use bwmgr to set emc freq Shared clocks on 4.9 have been deprecated. This has been replaced by tegra bandwidth managers. bug 200359628 Change-Id: Ib23ad57d36c501c16ade33d27d846f0d24217b34 Signed-off-by: Prateek Patel Reviewed-on: https://git-master.nvidia.com/r/1597879 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity Reviewed-by: Bharat Nihalani GVS: Gerrit_Virtual_Submit Reviewed-by: Sachin Nikam Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/platform/tegra/nvadsp/adsp_dfs.c | 147 +++-------------------- drivers/platform/tegra/nvadsp/dev-t18x.c | 18 --- drivers/platform/tegra/nvadsp/dev.c | 27 +++-- drivers/platform/tegra/nvadsp/dev.h | 1 - drivers/platform/tegra/nvadsp/os.c | 40 +++++- 5 files changed, 75 insertions(+), 158 deletions(-) diff --git a/drivers/platform/tegra/nvadsp/adsp_dfs.c b/drivers/platform/tegra/nvadsp/adsp_dfs.c index a12dc4f6..09d23c9b 100644 --- a/drivers/platform/tegra/nvadsp/adsp_dfs.c +++ b/drivers/platform/tegra/nvadsp/adsp_dfs.c @@ -100,7 +100,6 @@ struct adsp_dfs_policy { struct clk *adsp_clk; struct clk *aclk_clk; struct clk *adsp_cpu_abus_clk; - struct notifier_block rate_change_nb; struct nvadsp_mbox mbox; #ifdef CONFIG_DEBUG_FS @@ -126,7 +125,6 @@ struct adsp_freq_stats { static struct adsp_dfs_policy *policy; static struct adsp_freq_stats freq_stats; static struct device *device; -static struct clk *ape_emc_clk; static DEFINE_MUTEX(policy_mutex); @@ -265,37 +263,9 @@ static void adspfreq_stats_update(void) freq_stats.last_time = cur_time; } -/* adsp clock rate change notifier callback */ -static int adsp_dfs_rc_callback( - struct notifier_block *nb, unsigned long rate, void *v) -{ - unsigned long freq = rate / 1000; - int old_index, new_index = 0; - - /* update states */ - adspfreq_stats_update(); - - old_index = freq_stats.last_index; - adsp_get_target_freq(rate, &new_index); - if (old_index != new_index) - freq_stats.last_index = new_index; - - if (policy->ovr_freq && freq == policy->ovr_freq) { - /* Re-init ACTMON when user requested override freq is met */ - actmon_rate_change(freq, true); - policy->ovr_freq = 0; - } else - actmon_rate_change(freq, false); - - return NOTIFY_OK; -}; - static struct adsp_dfs_policy dfs_policy = { .enable = 1, .clk_name = "adsp_cpu", - .rate_change_nb = { - .notifier_call = adsp_dfs_rc_callback, - }, }; static int adsp_update_freq_handshake(unsigned long tfreq_hz, int index) @@ -396,16 +366,12 @@ static unsigned long update_freq(unsigned long freq_khz) efreq = adsp_to_emc_freq(tfreq_hz / 1000); - if (IS_ENABLED(CONFIG_COMMON_CLK)) { - tegra_bwmgr_set_emc(drv->bwmgr, efreq * 1000, - TEGRA_BWMGR_SET_EMC_FLOOR); - } else { - ret = clk_set_rate(ape_emc_clk, efreq * 1000); - if (ret) { - dev_err(device, "failed to set ape.emc clk:%d\n", ret); - policy->update_freq_flag = false; - goto err_out; - } + ret = tegra_bwmgr_set_emc(drv->bwmgr, efreq * 1000, + TEGRA_BWMGR_SET_EMC_FLOOR); + if (ret) { + dev_err(device, "failed to set emc freq rate:%d\n", ret); + policy->update_freq_flag = false; + goto err_out; } /* @@ -439,18 +405,14 @@ err_out: } efreq = adsp_to_emc_freq(old_freq_khz); - if (IS_ENABLED(CONFIG_COMMON_CLK)) { - tegra_bwmgr_set_emc(drv->bwmgr, efreq * 1000, - TEGRA_BWMGR_SET_EMC_FLOOR); - } else { - ret = clk_set_rate(ape_emc_clk, efreq * 1000); - if (ret) { - dev_err(device, - "failed to set ape.emc clk:%d\n", ret); - policy->update_freq_flag = false; - } - } + ret = tegra_bwmgr_set_emc(drv->bwmgr, efreq * 1000, + TEGRA_BWMGR_SET_EMC_FLOOR); + if (ret) { + dev_err(device, "failed to set emc freq rate:%d\n", + ret); + policy->update_freq_flag = false; + } tfreq_hz = old_freq_khz * 1000; } return tfreq_hz / 1000; @@ -853,29 +815,6 @@ int adsp_dfs_core_init(struct platform_device *pdev) if (ret) goto end; - if (IS_ENABLED(CONFIG_COMMON_CLK)) { - drv->bwmgr = tegra_bwmgr_register(TEGRA_BWMGR_CLIENT_APE_ADSP); - if (IS_ERR_OR_NULL(drv->bwmgr)) { - dev_err(&pdev->dev, "unable to register bwmgr\n"); - ret = PTR_ERR(drv->bwmgr); - goto end; - } - } else { - /* Change emc freq as per the adsp to emc lookup table */ - ape_emc_clk = clk_get_sys("ape", "emc"); - if (IS_ERR_OR_NULL(ape_emc_clk)) { - dev_err(device, "unable to find ape.emc clock\n"); - ret = PTR_ERR(ape_emc_clk); - goto end; - } - - ret = clk_prepare_enable(ape_emc_clk); - if (ret) { - dev_err(device, "unable to enable ape.emc clock\n"); - goto end; - } - } - policy->max = policy->cpu_max = drv->adsp_freq; /* adsp_freq in KHz */ policy->min = policy->cpu_min = adsp_cpu_freq_table[0] / 1000; @@ -884,15 +823,11 @@ int adsp_dfs_core_init(struct platform_device *pdev) efreq = adsp_to_emc_freq(policy->cur); - if (IS_ENABLED(CONFIG_COMMON_CLK)) { - tegra_bwmgr_set_emc(drv->bwmgr, efreq * 1000, - TEGRA_BWMGR_SET_EMC_FLOOR); - } else { - ret = clk_set_rate(ape_emc_clk, efreq * 1000); - if (ret) { - dev_err(device, "failed to set ape.emc clk:%d\n", ret); - goto end; - } + ret = tegra_bwmgr_set_emc(drv->bwmgr, efreq * 1000, + TEGRA_BWMGR_SET_EMC_FLOOR); + if (ret) { + dev_err(device, "failed to set emc freq rate:%d\n", ret); + goto end; } adsp_get_target_freq(policy->cur * 1000, &freq_stats.last_index); @@ -907,30 +842,6 @@ int adsp_dfs_core_init(struct platform_device *pdev) goto end; } -#if !defined(CONFIG_COMMON_CLK) - if (policy->rate_change_nb.notifier_call) { - /* - * "adsp_cpu" clk is a shared user of parent adsp_cpu_bus clk; - * rate change notification should come from bus clock itself. - */ - struct clk *p = clk_get_parent(policy->adsp_clk); - if (!p) { - dev_err(&pdev->dev, "Failed to find adsp cpu parent clock\n"); - ret = -EINVAL; - goto end; - } - - ret = tegra_register_clk_rate_notifier(p, - &policy->rate_change_nb); - if (ret) { - dev_err(&pdev->dev, "rate change notifier err: %s\n", - policy->clk_name); - nvadsp_mbox_close(&policy->mbox); - goto end; - } - } -#endif - #ifdef CONFIG_DEBUG_FS adsp_dfs_debugfs_init(pdev); #endif @@ -942,15 +853,6 @@ end: adsp_clk_put(policy); - if (IS_ENABLED(CONFIG_COMMON_CLK) && drv->bwmgr) { - tegra_bwmgr_set_emc(drv->bwmgr, 0, - TEGRA_BWMGR_SET_EMC_FLOOR); - tegra_bwmgr_unregister(drv->bwmgr); - } else if (ape_emc_clk) { - clk_disable_unprepare(ape_emc_clk); - clk_put(ape_emc_clk); - } - return ret; } @@ -968,21 +870,8 @@ int adsp_dfs_core_exit(struct platform_device *pdev) dev_info(&pdev->dev, "adsp dfs exit failed: mbox close error. ret:%d\n", ret); -#if !defined(CONFIG_COMMON_CLK) - tegra_unregister_clk_rate_notifier(clk_get_parent(policy->adsp_clk), - &policy->rate_change_nb); -#endif adsp_clk_put(policy); - if (IS_ENABLED(CONFIG_COMMON_CLK) && drv->bwmgr) { - tegra_bwmgr_set_emc(drv->bwmgr, 0, - TEGRA_BWMGR_SET_EMC_FLOOR); - tegra_bwmgr_unregister(drv->bwmgr); - } else if (ape_emc_clk) { - clk_disable_unprepare(ape_emc_clk); - clk_put(ape_emc_clk); - } - drv->dfs_initialized = false; dev_dbg(&pdev->dev, "adsp dfs has exited ....\n"); diff --git a/drivers/platform/tegra/nvadsp/dev-t18x.c b/drivers/platform/tegra/nvadsp/dev-t18x.c index 90eefef6..8aa8e744 100644 --- a/drivers/platform/tegra/nvadsp/dev-t18x.c +++ b/drivers/platform/tegra/nvadsp/dev-t18x.c @@ -58,11 +58,6 @@ static int nvadsp_t18x_clocks_disable(struct platform_device *pdev) drv_data->apb2ape_clk = NULL; } - if (drv_data->ape_emc_clk) { - clk_disable_unprepare(drv_data->ape_emc_clk); - dev_dbg(dev, "ape.emc clock disabled\n"); - drv_data->ape_emc_clk = NULL; - } return 0; } @@ -122,19 +117,6 @@ static int nvadsp_t18x_clocks_enable(struct platform_device *pdev) } dev_dbg(dev, "adsp neon clock enabled\n"); - drv_data->ape_emc_clk = devm_clk_get(dev, "adsp.emc"); - if (IS_ERR_OR_NULL(drv_data->ape_emc_clk)) { - dev_err(dev, "unable to find adsp.emc clock\n"); - ret = PTR_ERR(drv_data->ape_emc_clk); - goto end; - } - ret = clk_prepare_enable(drv_data->ape_emc_clk); - if (ret) { - dev_err(dev, "unable to enable adsp.emc clock\n"); - goto end; - } - dev_dbg(dev, "ape.emc is enabled\n"); - drv_data->apb2ape_clk = devm_clk_get(dev, "adsp.apb2ape"); if (IS_ERR_OR_NULL(drv_data->apb2ape_clk)) { dev_err(dev, "unable to find adsp.apb2ape clk\n"); diff --git a/drivers/platform/tegra/nvadsp/dev.c b/drivers/platform/tegra/nvadsp/dev.c index 621618ac..03cb86d4 100644 --- a/drivers/platform/tegra/nvadsp/dev.c +++ b/drivers/platform/tegra/nvadsp/dev.c @@ -330,17 +330,12 @@ static int __init nvadsp_probe(struct platform_device *pdev) if (ret) goto err; -#ifdef CONFIG_TEGRA_EMC_APE_DFS - ret = emc_dfs_init(pdev); - if (ret) - goto err; -#endif - #ifdef CONFIG_TEGRA_ADSP_ACTMON ret = ape_actmon_probe(pdev); if (ret) goto err; #endif + ret = nvadsp_os_probe(pdev); if (ret) goto err; @@ -360,6 +355,11 @@ static int __init nvadsp_probe(struct platform_device *pdev) ret = nvadsp_aram_init(aram_addr, aram_size); if (ret) dev_err(dev, "Failed to init aram\n"); + + drv_data->bwmgr = tegra_bwmgr_register(TEGRA_BWMGR_CLIENT_APE_ADSP); + ret = IS_ERR_OR_NULL(drv_data->bwmgr); + if (ret) + dev_err(&pdev->dev, "unable to register bwmgr\n"); err: #ifdef CONFIG_PM ret = pm_runtime_put_sync(dev); @@ -372,9 +372,18 @@ out: static int nvadsp_remove(struct platform_device *pdev) { -#ifdef CONFIG_TEGRA_EMC_APE_DFS - emc_dfs_exit(); -#endif + struct nvadsp_drv_data *drv_data = platform_get_drvdata(pdev); + int err; + + if (drv_data->bwmgr) { + err = tegra_bwmgr_set_emc(drv_data->bwmgr, 0, + TEGRA_BWMGR_SET_EMC_FLOOR); + if (err) { + dev_err(&pdev->dev, "failed to set emc freq rate:%d\n", + err); + } + tegra_bwmgr_unregister(drv_data->bwmgr); + } nvadsp_aram_exit(); pm_runtime_disable(&pdev->dev); diff --git a/drivers/platform/tegra/nvadsp/dev.h b/drivers/platform/tegra/nvadsp/dev.h index b8458280..91d64749 100644 --- a/drivers/platform/tegra/nvadsp/dev.h +++ b/drivers/platform/tegra/nvadsp/dev.h @@ -162,7 +162,6 @@ struct nvadsp_drv_data { struct clk *aclk_clk; struct clk *adsp_cpu_abus_clk; struct clk *adsp_neon_clk; - struct clk *ape_emc_clk; struct clk *uartape_clk; struct clk *ahub_clk; unsigned long adsp_freq; /* in KHz*/ diff --git a/drivers/platform/tegra/nvadsp/os.c b/drivers/platform/tegra/nvadsp/os.c index 5e8f6b64..99c088b8 100644 --- a/drivers/platform/tegra/nvadsp/os.c +++ b/drivers/platform/tegra/nvadsp/os.c @@ -770,6 +770,40 @@ u32 adsp_to_emc_freq(u32 adspfreq) return 0; /* emc min */ } +static int nvadsp_set_ape_emc_freq(struct nvadsp_drv_data *drv_data) +{ + unsigned long ape_emc_freq; + struct device *dev = &priv.pdev->dev; + int ret; + +#ifdef CONFIG_TEGRA_ADSP_DFS + /* pass adsp freq in KHz. adsp_emc_freq in Hz */ + ape_emc_freq = adsp_to_emc_freq(drv_data->adsp_freq / 1000) * 1000; +#else + ape_emc_freq = drv_data->ape_emc_freq * 1000; /* in Hz */ +#endif + dev_dbg(dev, "requested adsp cpu freq %luKHz", + drv_data->adsp_freq / 1000); + dev_dbg(dev, "emc freq %luHz\n", ape_emc_freq / 1000); + + /* + * ape_emc_freq is not required to set if adsp_freq + * is lesser than 204.8 MHz + */ + + if (!ape_emc_freq) + return 0; + + ret = tegra_bwmgr_set_emc(drv_data->bwmgr, ape_emc_freq * 1000, + TEGRA_BWMGR_SET_EMC_FLOOR); + if (ret) + dev_err(dev, "failed to set emc freq rate:%d\n", ret); + dev_dbg(dev, "ape.emc freq %luKHz\n", + tegra_bwmgr_get_emc_rate() / 1000); + + return ret; +} + static int nvadsp_set_ape_freq(struct nvadsp_drv_data *drv_data) { unsigned long ape_freq = drv_data->ape_freq * 1000; /* in Hz*/ @@ -983,7 +1017,11 @@ static int nvadsp_set_boot_freqs(struct nvadsp_drv_data *drv_data) if (ret) goto end; } - + if (drv_data->bwmgr) { + ret = nvadsp_set_ape_emc_freq(drv_data); + if (ret) + goto end; + } end: return ret; }