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 \
|
gr2d.o \
|
||||||
gr3d.o \
|
gr3d.o \
|
||||||
falcon.o \
|
falcon.o \
|
||||||
|
hwpm.o \
|
||||||
vic.o \
|
vic.o \
|
||||||
nvdec.o \
|
nvdec.o \
|
||||||
nvenc.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
|
// 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>
|
#include <linux/bitops.h>
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "falcon.h"
|
#include "falcon.h"
|
||||||
#include "riscv.h"
|
#include "riscv.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "hwpm.h"
|
||||||
|
|
||||||
#define NVDEC_FW_MTHD_ADDR_ACTMON_ACTIVE_MASK 0xCAU
|
#define NVDEC_FW_MTHD_ADDR_ACTMON_ACTIVE_MASK 0xCAU
|
||||||
#define NVDEC_FW_MTHD_ADDR_ACTMON_ACTIVE_BORPS 0xCBU
|
#define NVDEC_FW_MTHD_ADDR_ACTMON_ACTIVE_BORPS 0xCBU
|
||||||
@@ -58,6 +59,7 @@ struct nvdec_config {
|
|||||||
|
|
||||||
struct nvdec {
|
struct nvdec {
|
||||||
struct falcon falcon;
|
struct falcon falcon;
|
||||||
|
struct tegra_drm_hwpm hwpm;
|
||||||
|
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
struct tegra_drm_client client;
|
struct tegra_drm_client client;
|
||||||
@@ -844,6 +846,11 @@ static int nvdec_probe(struct platform_device *pdev)
|
|||||||
goto exit_actmon;
|
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_enable(dev);
|
||||||
pm_runtime_use_autosuspend(dev);
|
pm_runtime_use_autosuspend(dev);
|
||||||
pm_runtime_set_autosuspend_delay(dev, 500);
|
pm_runtime_set_autosuspend_delay(dev, 500);
|
||||||
@@ -865,6 +872,9 @@ static int nvdec_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
pm_runtime_disable(&pdev->dev);
|
pm_runtime_disable(&pdev->dev);
|
||||||
|
|
||||||
|
tegra_drm_hwpm_unregister(&nvdec->hwpm, pdev->resource[0].start,
|
||||||
|
TEGRA_DRM_HWPM_IP_NVDEC);
|
||||||
|
|
||||||
nvdec_devfreq_deinit(nvdec);
|
nvdec_devfreq_deinit(nvdec);
|
||||||
|
|
||||||
host1x_actmon_unregister(&nvdec->client.base);
|
host1x_actmon_unregister(&nvdec->client.base);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// 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>
|
#include <linux/bitops.h>
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
#include "falcon.h"
|
#include "falcon.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "hwpm.h"
|
||||||
|
|
||||||
#define NVENC_TFBIF_TRANSCFG 0x1844
|
#define NVENC_TFBIF_TRANSCFG 0x1844
|
||||||
#define NVENC_TFBIF_ACTMON_ACTIVE_MASK 0x184c
|
#define NVENC_TFBIF_ACTMON_ACTIVE_MASK 0x184c
|
||||||
@@ -48,6 +49,7 @@ struct nvenc_config {
|
|||||||
|
|
||||||
struct nvenc {
|
struct nvenc {
|
||||||
struct falcon falcon;
|
struct falcon falcon;
|
||||||
|
struct tegra_drm_hwpm hwpm;
|
||||||
|
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
struct tegra_drm_client client;
|
struct tegra_drm_client client;
|
||||||
@@ -710,6 +712,11 @@ static int nvenc_probe(struct platform_device *pdev)
|
|||||||
goto exit_actmon;
|
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_enable(dev);
|
||||||
pm_runtime_use_autosuspend(dev);
|
pm_runtime_use_autosuspend(dev);
|
||||||
pm_runtime_set_autosuspend_delay(dev, 500);
|
pm_runtime_set_autosuspend_delay(dev, 500);
|
||||||
@@ -731,6 +738,9 @@ static int nvenc_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
pm_runtime_disable(&pdev->dev);
|
pm_runtime_disable(&pdev->dev);
|
||||||
|
|
||||||
|
tegra_drm_hwpm_unregister(&nvenc->hwpm, pdev->resource[0].start,
|
||||||
|
TEGRA_DRM_HWPM_IP_NVENC);
|
||||||
|
|
||||||
nvenc_devfreq_deinit(nvenc);
|
nvenc_devfreq_deinit(nvenc);
|
||||||
|
|
||||||
host1x_actmon_unregister(&nvenc->client.base);
|
host1x_actmon_unregister(&nvenc->client.base);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// 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>
|
#include <linux/clk.h>
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "falcon.h"
|
#include "falcon.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "vic.h"
|
#include "vic.h"
|
||||||
|
#include "hwpm.h"
|
||||||
|
|
||||||
#define OFA_TFBIF_TRANSCFG 0x1444
|
#define OFA_TFBIF_TRANSCFG 0x1444
|
||||||
#define OFA_SAFETY_RAM_INIT_REQ 0x3320
|
#define OFA_SAFETY_RAM_INIT_REQ 0x3320
|
||||||
@@ -35,6 +36,7 @@ struct ofa_config {
|
|||||||
|
|
||||||
struct ofa {
|
struct ofa {
|
||||||
struct falcon falcon;
|
struct falcon falcon;
|
||||||
|
struct tegra_drm_hwpm hwpm;
|
||||||
|
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
struct tegra_drm_client client;
|
struct tegra_drm_client client;
|
||||||
@@ -368,6 +370,11 @@ static int ofa_probe(struct platform_device *pdev)
|
|||||||
goto exit_falcon;
|
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_enable(dev);
|
||||||
pm_runtime_use_autosuspend(dev);
|
pm_runtime_use_autosuspend(dev);
|
||||||
pm_runtime_set_autosuspend_delay(dev, 500);
|
pm_runtime_set_autosuspend_delay(dev, 500);
|
||||||
@@ -386,6 +393,9 @@ static int ofa_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
pm_runtime_disable(&pdev->dev);
|
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);
|
host1x_client_unregister(&ofa->client.base);
|
||||||
|
|
||||||
falcon_exit(&ofa->falcon);
|
falcon_exit(&ofa->falcon);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// 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>
|
#include <linux/bitops.h>
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "falcon.h"
|
#include "falcon.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "vic.h"
|
#include "vic.h"
|
||||||
|
#include "hwpm.h"
|
||||||
|
|
||||||
struct vic_config {
|
struct vic_config {
|
||||||
const char *firmware;
|
const char *firmware;
|
||||||
@@ -38,6 +39,7 @@ struct vic_config {
|
|||||||
|
|
||||||
struct vic {
|
struct vic {
|
||||||
struct falcon falcon;
|
struct falcon falcon;
|
||||||
|
struct tegra_drm_hwpm hwpm;
|
||||||
|
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
struct tegra_drm_client client;
|
struct tegra_drm_client client;
|
||||||
@@ -778,6 +780,11 @@ static int vic_probe(struct platform_device *pdev)
|
|||||||
goto exit_actmon;
|
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_enable(dev);
|
||||||
pm_runtime_use_autosuspend(dev);
|
pm_runtime_use_autosuspend(dev);
|
||||||
pm_runtime_set_autosuspend_delay(dev, 500);
|
pm_runtime_set_autosuspend_delay(dev, 500);
|
||||||
@@ -800,6 +807,9 @@ static int vic_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
pm_runtime_disable(&pdev->dev);
|
pm_runtime_disable(&pdev->dev);
|
||||||
|
|
||||||
|
tegra_drm_hwpm_unregister(&vic->hwpm, pdev->resource[0].start,
|
||||||
|
TEGRA_DRM_HWPM_IP_VIC);
|
||||||
|
|
||||||
vic_devfreq_deinit(vic);
|
vic_devfreq_deinit(vic);
|
||||||
|
|
||||||
host1x_actmon_unregister(&vic->client.base);
|
host1x_actmon_unregister(&vic->client.base);
|
||||||
|
|||||||
Reference in New Issue
Block a user