mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
tegra: hwpm: Add HWPM registration in Virt_engine
- HWPM driver to profile OFA, VIC and NVENC IPs. Hence add the IP-HWPM registration mechanism. - Power management is not implemented as IPs are expected to stay powered on as long as Guest-OS-0 stays powered on. - Register operations for Read, Write to be handled by exposing IP Perfmuxes within the hypervisor. Bug 4170733 DOS-SHR-7601 Change-Id: I2936e9cc5539b7a5c93993694fbd1d866e2f6877 Signed-off-by: vasukis <vasukis@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2948008 Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
e3ce443fc9
commit
842bf32431
@@ -3,6 +3,7 @@
|
||||
|
||||
ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
|
||||
ccflags-y += -I$(srctree.nvidia-oot)/drivers/gpu/drm/tegra/include
|
||||
ccflags-y += -I$(srctree.hwpm)/include
|
||||
|
||||
tegra-drm-next-y := \
|
||||
drm.o \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2022, NVIDIA Corporation.
|
||||
* Copyright (c) 2023, NVIDIA Corporation.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
#include "drm.h"
|
||||
|
||||
#ifndef CONFIG_TEGRA_SYSTEM_TYPE_ACK
|
||||
#include <uapi/linux/tegra-soc-hwpm-uapi.h>
|
||||
#endif
|
||||
|
||||
#define TEGRA_VHOST_CMD_CONNECT 0
|
||||
#define TEGRA_VHOST_CMD_DISCONNECT 1
|
||||
#define TEGRA_VHOST_CMD_SUSPEND 2
|
||||
@@ -327,12 +331,107 @@ static const struct of_device_id tegra_virt_engine_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tegra_virt_engine_of_match);
|
||||
|
||||
#ifndef CONFIG_TEGRA_SYSTEM_TYPE_ACK
|
||||
static u32 virt_engine_get_ip_index(const char *name)
|
||||
{
|
||||
if (strstr(name, "vic")) {
|
||||
return (u32)TEGRA_SOC_HWPM_RESOURCE_VIC;
|
||||
} else if (strstr(name, "nvenc")) {
|
||||
return (u32)TEGRA_SOC_HWPM_RESOURCE_NVENC;
|
||||
} else if (strstr(name, "ofa")) {
|
||||
return (u32)TEGRA_SOC_HWPM_RESOURCE_OFA;
|
||||
}
|
||||
return (u32)TERGA_SOC_HWPM_NUM_IPS;
|
||||
}
|
||||
|
||||
static u32 virt_engine_extract_base_addr(struct platform_device *pdev)
|
||||
{
|
||||
u32 hwpm_ip_index;
|
||||
u32 base_address;
|
||||
|
||||
hwpm_ip_index = virt_engine_get_ip_index(pdev->name);
|
||||
if (hwpm_ip_index == TEGRA_SOC_HWPM_RESOURCE_VIC) {
|
||||
base_address = 0x15340000;
|
||||
} else if (hwpm_ip_index == TEGRA_SOC_HWPM_RESOURCE_NVENC) {
|
||||
base_address = 0x154c0000;
|
||||
} else if (hwpm_ip_index == TEGRA_SOC_HWPM_RESOURCE_OFA) {
|
||||
base_address = 0x15a50000;
|
||||
} else {
|
||||
dev_err(&pdev->dev, "IP Base address not found");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return base_address;
|
||||
}
|
||||
|
||||
static int virt_engine_ip_pm(void *ip_dev, bool disable)
|
||||
{
|
||||
int err = 0;
|
||||
struct platform_device *pdev = (struct platform_device *)ip_dev;
|
||||
|
||||
if (disable) {
|
||||
dev_warn(&pdev->dev, "Power Mgmt not impleted in vhost_engine."
|
||||
"IP expected to be ON");
|
||||
} else {
|
||||
dev_warn(&pdev->dev, "Power Mgmt not impleted in vhost_engine."
|
||||
"IP expected to be ON");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int virt_engine_ip_reg_op(void *ip_dev,
|
||||
enum tegra_soc_hwpm_ip_reg_op reg_op,
|
||||
u32 inst_element_index, u64 reg_offset, u32 *reg_data)
|
||||
{
|
||||
struct platform_device *pdev = (struct platform_device *)ip_dev;
|
||||
u32 base_address;
|
||||
|
||||
base_address = virt_engine_extract_base_addr(pdev);
|
||||
if (base_address <= 0) {
|
||||
dev_err(&pdev->dev, "IP Base address not found. HWPM Reg_OP failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (reg_op == TEGRA_SOC_HWPM_IP_REG_OP_READ) {
|
||||
void __iomem *ptr = NULL;
|
||||
|
||||
reg_offset = reg_offset + base_address;
|
||||
ptr = ioremap(reg_offset, 0x4);
|
||||
if (!ptr) {
|
||||
dev_err(&pdev->dev, "Failed to map IP Perfmux register (0x%llx)",
|
||||
reg_offset);
|
||||
}
|
||||
*reg_data = __raw_readl(ptr);
|
||||
iounmap(ptr);
|
||||
} else if (reg_op == TEGRA_SOC_HWPM_IP_REG_OP_WRITE) {
|
||||
void __iomem *ptr = NULL;
|
||||
|
||||
reg_offset = reg_offset + base_address;
|
||||
|
||||
ptr = ioremap(reg_offset, 0x4);
|
||||
if (!ptr) {
|
||||
dev_err(&pdev->dev, "Failed to map IP Perfmux register (0x%llx)",
|
||||
reg_offset);
|
||||
}
|
||||
__raw_writel(*reg_data, ptr);
|
||||
iounmap(ptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int virt_engine_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
u32 module_id, class;
|
||||
struct virt_engine *virt;
|
||||
int err;
|
||||
#ifndef CONFIG_TEGRA_SYSTEM_TYPE_ACK
|
||||
struct tegra_soc_hwpm_ip_ops hwpm_ip_ops;
|
||||
u32 hwpm_ip_index;
|
||||
#endif
|
||||
|
||||
err = of_property_read_u32(pdev->dev.of_node, "nvidia,module-id", &module_id);
|
||||
if (err < 0) {
|
||||
@@ -399,6 +498,22 @@ static int virt_engine_probe(struct platform_device *pdev)
|
||||
|
||||
virt_engine_setup_actmon_debugfs(virt);
|
||||
|
||||
#ifndef CONFIG_TEGRA_SYSTEM_TYPE_ACK
|
||||
hwpm_ip_index = virt_engine_get_ip_index(pdev->name);
|
||||
if (hwpm_ip_index != TERGA_SOC_HWPM_NUM_IPS) {
|
||||
hwpm_ip_ops.ip_dev = (void *)pdev;
|
||||
hwpm_ip_ops.ip_base_address = virt_engine_extract_base_addr(pdev);
|
||||
if (hwpm_ip_ops.ip_base_address <= 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"IP Base address not found. HWPM-IP registration failed");
|
||||
return 0;
|
||||
}
|
||||
hwpm_ip_ops.resource_enum = hwpm_ip_index;
|
||||
hwpm_ip_ops.hwpm_ip_pm = &virt_engine_ip_pm;
|
||||
hwpm_ip_ops.hwpm_ip_reg_op = &virt_engine_ip_reg_op;
|
||||
tegra_soc_hwpm_ip_register(&hwpm_ip_ops);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
cleanup_ivc:
|
||||
@@ -413,7 +528,22 @@ static int virt_engine_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct virt_engine *virt_engine = platform_get_drvdata(pdev);
|
||||
int err;
|
||||
#ifndef CONFIG_TEGRA_SYSTEM_TYPE_ACK
|
||||
struct tegra_soc_hwpm_ip_ops hwpm_ip_ops;
|
||||
u32 hwpm_ip_index = virt_engine_get_ip_index(pdev->name);
|
||||
|
||||
if (hwpm_ip_index != TERGA_SOC_HWPM_NUM_IPS) {
|
||||
hwpm_ip_ops.ip_dev = (void *)pdev;
|
||||
hwpm_ip_ops.ip_base_address = virt_engine_extract_base_addr(pdev);
|
||||
if (hwpm_ip_ops.ip_base_address <= 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"IP Base address not found. HWPM-IP Un-register failed");
|
||||
return 0;
|
||||
}
|
||||
hwpm_ip_ops.resource_enum = hwpm_ip_index;
|
||||
tegra_soc_hwpm_ip_unregister(&hwpm_ip_ops);
|
||||
}
|
||||
#endif
|
||||
virt_engine_cleanup_actmon_debugfs(virt_engine);
|
||||
virt_engine_cleanup();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user