mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
nvadsp: Add Interconnect support for ADSP
Add Interconnect API support for ADSP Memory bandwidth requirement handling. From Kernel 4.14 and beyond - On T23X and newer platforms, the interconnects driver will be initialized and calls to BWMGR will be stubbed out. - On T194 and earlier platforms, BWMGR driver will be initialized and calls to interconnect framework will be stubbed out. Added code check with K5.9 as mc_utils.h header is present from K5.9 build For Kernel 4.9 and earlier - T23x will not be supported. - T194 and earlier platforms will use BWMGR. Interconnect framework is not available. JIRA TAS-1060 Change-Id: Ie0b4040f374a3c6102cb7aff2506d8cf2f0eab69 Signed-off-by: Mohan Kumar <mkumard@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2414369 Reviewed-by: Viswanath L <viswanathl@nvidia.com> Reviewed-by: Sameer Pujar <spujar@nvidia.com> Reviewed-by: Sharad Gupta <sharadg@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Laxman Dewangan
parent
3b69d4961c
commit
4464d26007
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* adsp dynamic frequency scaling
|
||||
*
|
||||
* Copyright (C) 2014-2019, NVIDIA Corporation. All rights reserved.
|
||||
* Copyright (C) 2014-2020, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
@@ -361,10 +361,8 @@ static unsigned long update_freq(unsigned long freq_khz)
|
||||
|
||||
efreq = adsp_to_emc_freq(tfreq_hz / 1000);
|
||||
|
||||
ret = tegra_bwmgr_set_emc(drv->bwmgr, efreq * 1000,
|
||||
TEGRA_BWMGR_SET_EMC_FLOOR);
|
||||
ret = nvadsp_set_bw(drv, efreq);
|
||||
if (ret) {
|
||||
dev_err(device, "failed to set emc freq rate:%d\n", ret);
|
||||
policy->update_freq_flag = false;
|
||||
goto err_out;
|
||||
}
|
||||
@@ -401,13 +399,10 @@ err_out:
|
||||
|
||||
efreq = adsp_to_emc_freq(old_freq_khz);
|
||||
|
||||
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);
|
||||
ret = nvadsp_set_bw(drv, efreq);
|
||||
if (ret)
|
||||
policy->update_freq_flag = false;
|
||||
}
|
||||
|
||||
tfreq_hz = old_freq_khz * 1000;
|
||||
}
|
||||
return tfreq_hz / 1000;
|
||||
@@ -829,12 +824,9 @@ int adsp_dfs_core_init(struct platform_device *pdev)
|
||||
|
||||
efreq = adsp_to_emc_freq(policy->cur);
|
||||
|
||||
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);
|
||||
ret = nvadsp_set_bw(drv, efreq);
|
||||
if (ret)
|
||||
goto end;
|
||||
}
|
||||
|
||||
adsp_get_target_freq(policy->cur * 1000, &freq_stats.last_index);
|
||||
freq_stats.last_time = get_jiffies_64();
|
||||
|
||||
@@ -136,6 +136,73 @@ uint64_t nvadsp_get_timestamp_counter(void)
|
||||
}
|
||||
EXPORT_SYMBOL(nvadsp_get_timestamp_counter);
|
||||
|
||||
int nvadsp_set_bw(struct nvadsp_drv_data *drv_data, u32 efreq)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (drv_data->bwmgr)
|
||||
ret = tegra_bwmgr_set_emc(drv_data->bwmgr, efreq * 1000,
|
||||
TEGRA_BWMGR_SET_EMC_FLOOR);
|
||||
#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
|
||||
else if (drv_data->icc_path_handle)
|
||||
ret = icc_set_bw(drv_data->icc_path_handle, 0,
|
||||
(unsigned long)FREQ2ICC(efreq * 1000));
|
||||
#endif
|
||||
if (ret)
|
||||
dev_err(&drv_data->pdev->dev,
|
||||
"failed to set emc freq rate:%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nvadsp_bw_register(struct nvadsp_drv_data *drv_data)
|
||||
{
|
||||
struct device *dev = &drv_data->pdev->dev;
|
||||
|
||||
switch (tegra_get_chip_id()) {
|
||||
case TEGRA210:
|
||||
case TEGRA186:
|
||||
case TEGRA194:
|
||||
drv_data->bwmgr = tegra_bwmgr_register(
|
||||
TEGRA_BWMGR_CLIENT_APE_ADSP);
|
||||
if (IS_ERR(drv_data->bwmgr)) {
|
||||
dev_err(dev, "unable to register bwmgr\n");
|
||||
drv_data->bwmgr = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
|
||||
/* Interconnect Support */
|
||||
drv_data->icc_path_handle = icc_get(dev, TEGRA_ICC_APE,
|
||||
TEGRA_ICC_PRIMARY);
|
||||
if (IS_ERR(drv_data->icc_path_handle)) {
|
||||
dev_err(dev,
|
||||
"%s: Failed to register Interconnect. err=%ld\n",
|
||||
__func__, PTR_ERR(drv_data->icc_path_handle));
|
||||
drv_data->icc_path_handle = NULL;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void nvadsp_bw_unregister(struct nvadsp_drv_data *drv_data)
|
||||
{
|
||||
nvadsp_set_bw(drv_data, 0);
|
||||
|
||||
if (drv_data->bwmgr) {
|
||||
tegra_bwmgr_unregister(drv_data->bwmgr);
|
||||
drv_data->bwmgr = NULL;
|
||||
}
|
||||
|
||||
#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
|
||||
if (drv_data->icc_path_handle) {
|
||||
icc_put(drv_data->icc_path_handle);
|
||||
drv_data->icc_path_handle = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __init nvadsp_parse_clk_entries(struct platform_device *pdev)
|
||||
{
|
||||
struct nvadsp_drv_data *drv_data = platform_get_drvdata(pdev);
|
||||
@@ -376,10 +443,7 @@ static int __init nvadsp_probe(struct platform_device *pdev)
|
||||
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");
|
||||
nvadsp_bw_register(drv_data);
|
||||
err:
|
||||
#ifdef CONFIG_PM
|
||||
ret = pm_runtime_put_sync(dev);
|
||||
@@ -393,17 +457,9 @@ out:
|
||||
static int nvadsp_remove(struct platform_device *pdev)
|
||||
{
|
||||
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_bw_unregister(drv_data);
|
||||
|
||||
nvadsp_aram_exit();
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* A header file for Host driver for ADSP and APE
|
||||
*
|
||||
* Copyright (C) 2014-2019, NVIDIA Corporation. All rights reserved.
|
||||
* Copyright (C) 2014-2020, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
@@ -25,6 +25,11 @@
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
#include <linux/platform/tegra/emc_bwmgr.h>
|
||||
#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
|
||||
#include <linux/platform/tegra/mc_utils.h>
|
||||
#include <dt-bindings/interconnect/tegra_icc_id.h>
|
||||
#include <linux/interconnect.h>
|
||||
#endif
|
||||
|
||||
#include "hwmailbox.h"
|
||||
#include "amc.h"
|
||||
@@ -89,6 +94,9 @@ enum adsp_unit_fpga_reset {
|
||||
#define AMISC_REG_MBOX_OFFSET 0x64
|
||||
#define ADSP_ACTMON_REG_START_OFFSET 0x800
|
||||
#define ADSP_ACTMON_REG_END_OFFSET 0x828
|
||||
#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
|
||||
#define FREQ2ICC(x) (Bps_to_icc(emc_freq_to_bw(x)))
|
||||
#endif
|
||||
|
||||
enum nvadsp_virqs {
|
||||
MBOX_SEND_VIRQ,
|
||||
@@ -214,6 +222,9 @@ struct nvadsp_drv_data {
|
||||
int agic_irqs[NVADSP_VIRQ_MAX];
|
||||
|
||||
struct tegra_bwmgr_client *bwmgr;
|
||||
#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
|
||||
struct icc_path *icc_path_handle; /* icc_path handle handle */
|
||||
#endif
|
||||
u32 evp_base[ADSP_EVP_END];
|
||||
|
||||
const struct nvadsp_chipdata *chip_data;
|
||||
@@ -227,6 +238,7 @@ status_t nvadsp_mbox_init(struct platform_device *pdev);
|
||||
|
||||
int nvadsp_setup_amc_interrupts(struct platform_device *pdev);
|
||||
void nvadsp_free_amc_interrupts(struct platform_device *pdev);
|
||||
int nvadsp_set_bw(struct nvadsp_drv_data *drv, u32 efreq);
|
||||
|
||||
#ifdef CONFIG_TEGRA_ADSP_DFS
|
||||
void adsp_cpu_set_rate(unsigned long freq);
|
||||
|
||||
@@ -936,10 +936,7 @@ static int nvadsp_set_ape_emc_freq(struct nvadsp_drv_data *drv_data)
|
||||
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);
|
||||
ret = nvadsp_set_bw(drv_data, ape_emc_freq);
|
||||
dev_dbg(dev, "ape.emc freq %luKHz\n",
|
||||
tegra_bwmgr_get_emc_rate() / 1000);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user