Commit 6ca1701c authored by Aaron Kling's avatar Aaron Kling Committed by Lyude Paul
Browse files

drm/nouveau: Support devfreq for Tegra



Using pmu counters for usage stats. This enables dynamic frequency
scaling on all of the currently supported Tegra gpus.

The register offsets are valid for gk20a, gm20b, gp10b, and gv11b. If
support is added for ga10b, this will need rearchitected.

Signed-off-by: default avatarAaron Kling <webgeek1234@gmail.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
[fixed tab alignment in gk20a_devfreq_target()]
Signed-off-by: default avatarLyude Paul <lyude@redhat.com>
Link: https://lore.kernel.org/r/20250906-gk20a-devfreq-v2-1-0217f53ee355@gmail.com
parent d5603737
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ config DRM_NOUVEAU
	select THERMAL if ACPI && X86
	select ACPI_VIDEO if ACPI && X86
	select SND_HDA_COMPONENT if SND_HDA_CORE
	select PM_DEVFREQ if ARCH_TEGRA
	help
	  Choose this option for open-source NVIDIA support.

+2 −0
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@ struct nvkm_device_tegra {
	struct nvkm_device device;
	struct platform_device *pdev;

	void __iomem *regs;

	struct reset_control *rst;
	struct clk *clk;
	struct clk *clk_ref;
+20 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@
 */
#include "nouveau_platform.h"

#include <nvkm/subdev/clk/gk20a_devfreq.h>

static int nouveau_platform_probe(struct platform_device *pdev)
{
	const struct nvkm_device_tegra_func *func;
@@ -40,6 +42,21 @@ static void nouveau_platform_remove(struct platform_device *pdev)
	nouveau_drm_device_remove(drm);
}

#ifdef CONFIG_PM_SLEEP
static int nouveau_platform_suspend(struct device *dev)
{
	return gk20a_devfreq_suspend(dev);
}

static int nouveau_platform_resume(struct device *dev)
{
	return gk20a_devfreq_resume(dev);
}

static SIMPLE_DEV_PM_OPS(nouveau_pm_ops, nouveau_platform_suspend,
			 nouveau_platform_resume);
#endif

#if IS_ENABLED(CONFIG_OF)
static const struct nvkm_device_tegra_func gk20a_platform_data = {
	.iommu_bit = 34,
@@ -81,6 +98,9 @@ struct platform_driver nouveau_platform_driver = {
	.driver = {
		.name = "nouveau",
		.of_match_table = of_match_ptr(nouveau_platform_match),
#ifdef CONFIG_PM_SLEEP
		.pm = &nouveau_pm_ops,
#endif
	},
	.probe = nouveau_platform_probe,
	.remove = nouveau_platform_remove,
+4 −0
Original line number Diff line number Diff line
@@ -259,6 +259,10 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
	tdev->func = func;
	tdev->pdev = pdev;

	tdev->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(tdev->regs))
		return PTR_ERR(tdev->regs);

	if (func->require_vdd) {
		tdev->vdd = devm_regulator_get(&pdev->dev, "vdd");
		if (IS_ERR(tdev->vdd)) {
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ nvkm-y += nvkm/subdev/clk/gk104.o
nvkm-y += nvkm/subdev/clk/gk20a.o
nvkm-y += nvkm/subdev/clk/gm20b.o
nvkm-y += nvkm/subdev/clk/gp10b.o
nvkm-$(CONFIG_PM_DEVFREQ) += nvkm/subdev/clk/gk20a_devfreq.o

nvkm-y += nvkm/subdev/clk/pllnv04.o
nvkm-y += nvkm/subdev/clk/pllgt215.o
Loading