diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile index dbc97d3a..dc5d6bf4 100644 --- a/drivers/gpu/drm/tegra/Makefile +++ b/drivers/gpu/drm/tegra/Makefile @@ -27,6 +27,7 @@ tegra-drm-next-y := \ gr2d.o \ gr3d.o \ falcon.o \ + hwpm.o \ vic.o \ nvdec.o \ nvenc.o \ diff --git a/drivers/gpu/drm/tegra/hwpm.c b/drivers/gpu/drm/tegra/hwpm.c new file mode 100644 index 00000000..3cd8a7db --- /dev/null +++ b/drivers/gpu/drm/tegra/hwpm.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA Corporation. + */ + +#include +#include +#include + +#include + +#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 diff --git a/drivers/gpu/drm/tegra/hwpm.h b/drivers/gpu/drm/tegra/hwpm.h new file mode 100644 index 00000000..778e9223 --- /dev/null +++ b/drivers/gpu/drm/tegra/hwpm.h @@ -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 + +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_ */ \ No newline at end of file diff --git a/drivers/gpu/drm/tegra/nvdec.c b/drivers/gpu/drm/tegra/nvdec.c index 18a017d3..ce0b5a8d 100644 --- a/drivers/gpu/drm/tegra/nvdec.c +++ b/drivers/gpu/drm/tegra/nvdec.c @@ -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 @@ -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); diff --git a/drivers/gpu/drm/tegra/nvenc.c b/drivers/gpu/drm/tegra/nvenc.c index e7c1c13f..696c28f3 100644 --- a/drivers/gpu/drm/tegra/nvenc.c +++ b/drivers/gpu/drm/tegra/nvenc.c @@ -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 @@ -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); diff --git a/drivers/gpu/drm/tegra/ofa.c b/drivers/gpu/drm/tegra/ofa.c index d900d5ca..95ad4d04 100644 --- a/drivers/gpu/drm/tegra/ofa.c +++ b/drivers/gpu/drm/tegra/ofa.c @@ -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 @@ -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); diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index 79f02bd1..ff71c0bb 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -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 @@ -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);