mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
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:
committed by
mobile promotions
parent
ece68dd0d1
commit
cbf177852b
@@ -27,6 +27,7 @@ tegra-drm-next-y := \
|
||||
gr2d.o \
|
||||
gr3d.o \
|
||||
falcon.o \
|
||||
hwpm.o \
|
||||
vic.o \
|
||||
nvdec.o \
|
||||
nvenc.o \
|
||||
|
||||
116
drivers/gpu/drm/tegra/hwpm.c
Normal file
116
drivers/gpu/drm/tegra/hwpm.c
Normal 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
|
||||
29
drivers/gpu/drm/tegra/hwpm.h
Normal file
29
drivers/gpu/drm/tegra/hwpm.h
Normal 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_ */
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user