diff options
author | Daniel Lezcano <daniel.lezcano@linaro.org> | 2021-06-24 09:39:42 +0200 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2021-06-29 00:06:39 +0200 |
commit | 70e1deb642a939d14dd9b0391d8219cf21a03253 (patch) | |
tree | f1ef2b1e21c777c8d29529529d3417528d07b260 | |
parent | 2182a9a72de2187b74549490945a31bcea923a62 (diff) | |
download | linux-70e1deb642a939d14dd9b0391d8219cf21a03253.tar.gz |
arm64: soc: rockchip: Add SoC specific DTPM definitions
The SoC code is in charge of creating the dtpm hierarchy.
The rk3399 SoC has an energy model defined and two performance
domains. Create a DTPM SoC hierarchy based on these device where we
can limit the power and read the power consumption.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-rw-r--r-- | drivers/soc/rockchip/Kconfig | 8 | ||||
-rw-r--r-- | drivers/soc/rockchip/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/rockchip/dtpm.c | 97 |
3 files changed, 106 insertions, 0 deletions
diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig index 2c13bf4dd5db..fcdecea9169d 100644 --- a/drivers/soc/rockchip/Kconfig +++ b/drivers/soc/rockchip/Kconfig @@ -34,4 +34,12 @@ config ROCKCHIP_PM_DOMAINS If unsure, say N. +config ROCKCHIP_DTPM + tristate "Dynamic thermal power management support" + depends on DTPM_CPU && DTPM_DEVFREQ && DRM_PANFROST + help + Say y here to enable the dynamic thermal power management + for Rockchip. It will allow to do power capping on the + devices which are capable of that. + endif diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile index 875032f7344e..05f31a4e743c 100644 --- a/drivers/soc/rockchip/Makefile +++ b/drivers/soc/rockchip/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_ROCKCHIP_GRF) += grf.o obj-$(CONFIG_ROCKCHIP_IODOMAIN) += io-domain.o obj-$(CONFIG_ROCKCHIP_PM_DOMAINS) += pm_domains.o +obj-$(CONFIG_ROCKCHIP_DTPM) += dtpm.o diff --git a/drivers/soc/rockchip/dtpm.c b/drivers/soc/rockchip/dtpm.c new file mode 100644 index 000000000000..3137b523c1ea --- /dev/null +++ b/drivers/soc/rockchip/dtpm.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2021 Linaro Limited + * + * Author: Daniel Lezcano <daniel.lezcano@linaro.org> + * + * The powercap based Dynamic Thermal Power Management framework + * provides to the userspace a consistent API to set the power limit + * on some devices. + * + * DTPM defines the functions to create a tree of constraints. Each + * parent node is a virtual description of the aggregation of the + * children. It propagates the constraints set at its level to its + * children and collect the children power information. The leaves of + * the tree are the real devices which have the ability to get their + * current power consumption and set their power limit. + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/dtpm.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/slab.h> + +/* + * Here we want to create the following hierarchy: + * + * soc + * | + * |--little (cpu-pd0) + * | + * `--big (cpu-pd1) + * + */ +static struct dtpm *soc; + +static __init int dtpm_rock_cb(struct device_node *node, const char *name, + struct dtpm *parent) +{ + struct dtpm *dtpm; + int ret; + + dtpm = dtpm_of_find(node, 0); + if (!dtpm) + return -ENXIO; + + ret = dtpm_register(name, dtpm, parent); + if (ret) + return ret; + + /* End browsing the cpu list */ + return 1; +} + +static __init int dtpm_rock_init(void) +{ + const char *powerzones[] = { + "cpu-pd0", "cpu-pd1", + }; + + int i, ret; + + ret = dtpm_probe(); + if (ret) + return ret; + + soc = kzalloc(sizeof(*soc), GFP_KERNEL); + if (!soc) + return -ENOMEM; + + dtpm_init(soc, NULL); + + ret = dtpm_register("soc", soc, NULL); + if (ret) { + pr_err("Failed to register 'soc': %d\n", ret); + return ret; + } + + for (i = 0; i < ARRAY_SIZE(powerzones); i++) { + + ret = dtpm_of_for_each(powerzones[i], soc, dtpm_rock_cb); + if (ret && ret < 0) + pr_err("Failed to create '%s' dtpm entry: %d\n", + powerzones[i], ret); + + } + + return 0; +} +late_initcall_sync(dtpm_rock_init); + +static __exit void dtpm_rock_exit(void) +{ + dtpm_unregister(soc); +} +module_exit(dtpm_rock_exit); |