drm/tegra: add hwpm support in video ip driver

Add IP-HWPM interface in NVENC, OFA and VIC drivers. This code will
- register with HWPM driver during probe
- expose power management and register read/write function.

Bug 4158030

Change-Id: I9311c9fc31cffadf11c36b6e4516f0da84dcbdf4
Signed-off-by: Vedashree Vidwans <vvidwans@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2954070
Reviewed-by: Santosh BS <santoshb@nvidia.com>
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Vedashree Vidwans
2023-09-08 09:25:05 -07:00
committed by mobile promotions
parent ece68dd0d1
commit cbf177852b
7 changed files with 190 additions and 4 deletions

View File

@@ -27,6 +27,7 @@ tegra-drm-next-y := \
gr2d.o \
gr3d.o \
falcon.o \
hwpm.o \
vic.o \
nvdec.o \
nvenc.o \

View File

@@ -0,0 +1,116 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA Corporation.
*/
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/io.h>
#include <uapi/linux/tegra-soc-hwpm-uapi.h>
#include "hwpm.h"
#ifdef CONFIG_TEGRA_SYSTEM_TYPE_ACK
void tegra_drm_hwpm_register(struct tegra_drm_hwpm *drm_hwpm, u64 resource_base,
enum tegra_drm_hwpm_ip hwpm_ip)
{
}
void tegra_drm_hwpm_unregister(struct tegra_drm_hwpm *drm_hwpm, u64 resource_base,
enum tegra_drm_hwpm_ip hwpm_ip)
{
}
#else
static u32 tegra_drm_hwpm_readl(struct tegra_drm_hwpm *hwpm, u32 offset)
{
return readl(hwpm->regs + offset);
}
static void tegra_drm_hwpm_writel(struct tegra_drm_hwpm *hwpm, u32 value, u32 offset)
{
writel(value, hwpm->regs + offset);
}
static int tegra_drm_hwpm_ip_pm(void *ip_dev, bool disable)
{
int err = 0;
struct tegra_drm_hwpm *hwpm = (struct tegra_drm_hwpm *)ip_dev;
if (disable) {
err = pm_runtime_resume_and_get(hwpm->dev);
if (err < 0) {
dev_err(hwpm->dev, "runtime resume failed %d", err);
}
} else {
err = pm_runtime_put_autosuspend(hwpm->dev);
if (err < 0) {
dev_err(hwpm->dev, "runtime suspend failed %d", err);
}
}
return err;
}
static int tegra_drm_hwpm_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 tegra_drm_hwpm *hwpm = (struct tegra_drm_hwpm *)ip_dev;
if (reg_op == TEGRA_SOC_HWPM_IP_REG_OP_READ) {
*reg_data = tegra_drm_hwpm_readl(hwpm, reg_offset);
} else if (reg_op == TEGRA_SOC_HWPM_IP_REG_OP_WRITE) {
tegra_drm_hwpm_writel(hwpm, *reg_data, reg_offset);
}
return 0;
}
static u32 tegra_drm_hwpm_get_resource_index(enum tegra_drm_hwpm_ip hwpm_ip)
{
switch (hwpm_ip) {
case TEGRA_DRM_HWPM_IP_OFA:
return TEGRA_SOC_HWPM_RESOURCE_OFA;
break;
case TEGRA_DRM_HWPM_IP_NVDEC:
return TEGRA_SOC_HWPM_RESOURCE_NVDEC;
break;
case TEGRA_DRM_HWPM_IP_NVENC:
return TEGRA_SOC_HWPM_RESOURCE_NVENC;
break;
case TEGRA_DRM_HWPM_IP_VIC:
return TEGRA_SOC_HWPM_RESOURCE_VIC;
break;
case TEGRA_DRM_HWPM_IP_INVALID:
default:
return TERGA_SOC_HWPM_NUM_RESOURCES;
break;
}
}
void tegra_drm_hwpm_register(struct tegra_drm_hwpm *drm_hwpm, u64 resource_base,
enum tegra_drm_hwpm_ip hwpm_ip)
{
struct tegra_soc_hwpm_ip_ops hwpm_ip_ops;
hwpm_ip_ops.ip_dev = (void *)drm_hwpm;
hwpm_ip_ops.ip_base_address = resource_base;
hwpm_ip_ops.resource_enum = tegra_drm_hwpm_get_resource_index(hwpm_ip);
hwpm_ip_ops.hwpm_ip_pm = &tegra_drm_hwpm_ip_pm;
hwpm_ip_ops.hwpm_ip_reg_op = &tegra_drm_hwpm_ip_reg_op;
tegra_soc_hwpm_ip_register(&hwpm_ip_ops);
}
void tegra_drm_hwpm_unregister(struct tegra_drm_hwpm *drm_hwpm, u64 resource_base,
enum tegra_drm_hwpm_ip hwpm_ip)
{
struct tegra_soc_hwpm_ip_ops hwpm_ip_ops;
hwpm_ip_ops.ip_dev = (void *)drm_hwpm;
hwpm_ip_ops.ip_base_address = resource_base;
hwpm_ip_ops.resource_enum = tegra_drm_hwpm_get_resource_index(hwpm_ip);
tegra_soc_hwpm_ip_unregister(&hwpm_ip_ops);
}
#endif

View File

@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA Corporation.
*/
#ifndef _TEGRA_DRM_HWPM_H_
#define _TEGRA_DRM_HWPM_H_
#include <linux/types.h>
struct tegra_drm_hwpm {
struct device *dev;
void __iomem *regs;
};
enum tegra_drm_hwpm_ip {
TEGRA_DRM_HWPM_IP_INVALID,
TEGRA_DRM_HWPM_IP_OFA,
TEGRA_DRM_HWPM_IP_NVDEC,
TEGRA_DRM_HWPM_IP_NVENC,
TEGRA_DRM_HWPM_IP_VIC
};
void tegra_drm_hwpm_register(struct tegra_drm_hwpm *drm_hwpm, u64 resource_base,
enum tegra_drm_hwpm_ip hwpm_ip);
void tegra_drm_hwpm_unregister(struct tegra_drm_hwpm *drm_hwpm, u64 resource_base,
enum tegra_drm_hwpm_ip hwpm_ip);
#endif /* _TEGRA_DRM_HWPM_H_ */

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
* SPDX-FileCopyrightText: Copyright (c) 2015-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
*/
#include <linux/bitops.h>
@@ -29,6 +29,7 @@
#include "falcon.h"
#include "riscv.h"
#include "util.h"
#include "hwpm.h"
#define NVDEC_FW_MTHD_ADDR_ACTMON_ACTIVE_MASK 0xCAU
#define NVDEC_FW_MTHD_ADDR_ACTMON_ACTIVE_BORPS 0xCBU
@@ -58,6 +59,7 @@ struct nvdec_config {
struct nvdec {
struct falcon falcon;
struct tegra_drm_hwpm hwpm;
void __iomem *regs;
struct tegra_drm_client client;
@@ -844,6 +846,11 @@ static int nvdec_probe(struct platform_device *pdev)
goto exit_actmon;
}
nvdec->hwpm.dev = dev;
nvdec->hwpm.regs = nvdec->regs;
tegra_drm_hwpm_register(&nvdec->hwpm, pdev->resource[0].start,
TEGRA_DRM_HWPM_IP_NVDEC);
pm_runtime_enable(dev);
pm_runtime_use_autosuspend(dev);
pm_runtime_set_autosuspend_delay(dev, 500);
@@ -865,6 +872,9 @@ static int nvdec_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
tegra_drm_hwpm_unregister(&nvdec->hwpm, pdev->resource[0].start,
TEGRA_DRM_HWPM_IP_NVDEC);
nvdec_devfreq_deinit(nvdec);
host1x_actmon_unregister(&nvdec->client.base);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
* SPDX-FileCopyrightText: Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
*/
#include <linux/bitops.h>
@@ -26,6 +26,7 @@
#include "drm.h"
#include "falcon.h"
#include "util.h"
#include "hwpm.h"
#define NVENC_TFBIF_TRANSCFG 0x1844
#define NVENC_TFBIF_ACTMON_ACTIVE_MASK 0x184c
@@ -48,6 +49,7 @@ struct nvenc_config {
struct nvenc {
struct falcon falcon;
struct tegra_drm_hwpm hwpm;
void __iomem *regs;
struct tegra_drm_client client;
@@ -710,6 +712,11 @@ static int nvenc_probe(struct platform_device *pdev)
goto exit_actmon;
}
nvenc->hwpm.dev = dev;
nvenc->hwpm.regs = nvenc->regs;
tegra_drm_hwpm_register(&nvenc->hwpm, pdev->resource[0].start,
TEGRA_DRM_HWPM_IP_NVENC);
pm_runtime_enable(dev);
pm_runtime_use_autosuspend(dev);
pm_runtime_set_autosuspend_delay(dev, 500);
@@ -731,6 +738,9 @@ static int nvenc_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
tegra_drm_hwpm_unregister(&nvenc->hwpm, pdev->resource[0].start,
TEGRA_DRM_HWPM_IP_NVENC);
nvenc_devfreq_deinit(nvenc);
host1x_actmon_unregister(&nvenc->client.base);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021-2022, NVIDIA Corporation.
* SPDX-FileCopyrightText: Copyright (c) 2021-2023, NVIDIA Corporation.
*/
#include <linux/clk.h>
@@ -22,6 +22,7 @@
#include "falcon.h"
#include "util.h"
#include "vic.h"
#include "hwpm.h"
#define OFA_TFBIF_TRANSCFG 0x1444
#define OFA_SAFETY_RAM_INIT_REQ 0x3320
@@ -35,6 +36,7 @@ struct ofa_config {
struct ofa {
struct falcon falcon;
struct tegra_drm_hwpm hwpm;
void __iomem *regs;
struct tegra_drm_client client;
@@ -368,6 +370,11 @@ static int ofa_probe(struct platform_device *pdev)
goto exit_falcon;
}
ofa->hwpm.dev = dev;
ofa->hwpm.regs = ofa->regs;
tegra_drm_hwpm_register(&ofa->hwpm, pdev->resource[0].start,
TEGRA_DRM_HWPM_IP_OFA);
pm_runtime_enable(dev);
pm_runtime_use_autosuspend(dev);
pm_runtime_set_autosuspend_delay(dev, 500);
@@ -386,6 +393,9 @@ static int ofa_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
tegra_drm_hwpm_unregister(&ofa->hwpm, pdev->resource[0].start,
TEGRA_DRM_HWPM_IP_OFA);
host1x_client_unregister(&ofa->client.base);
falcon_exit(&ofa->falcon);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2015-2023 NVIDIA CORPORATION. All rights reserved.
* SPDX-FileCopyrightText: Copyright (C) 2015-2023 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/bitops.h>
@@ -28,6 +28,7 @@
#include "falcon.h"
#include "util.h"
#include "vic.h"
#include "hwpm.h"
struct vic_config {
const char *firmware;
@@ -38,6 +39,7 @@ struct vic_config {
struct vic {
struct falcon falcon;
struct tegra_drm_hwpm hwpm;
void __iomem *regs;
struct tegra_drm_client client;
@@ -778,6 +780,11 @@ static int vic_probe(struct platform_device *pdev)
goto exit_actmon;
}
vic->hwpm.dev = dev;
vic->hwpm.regs = vic->regs;
tegra_drm_hwpm_register(&vic->hwpm, pdev->resource[0].start,
TEGRA_DRM_HWPM_IP_VIC);
pm_runtime_enable(dev);
pm_runtime_use_autosuspend(dev);
pm_runtime_set_autosuspend_delay(dev, 500);
@@ -800,6 +807,9 @@ static int vic_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
tegra_drm_hwpm_unregister(&vic->hwpm, pdev->resource[0].start,
TEGRA_DRM_HWPM_IP_VIC);
vic_devfreq_deinit(vic);
host1x_actmon_unregister(&vic->client.base);