From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
To: Manaf Meethalavalappu Pallikunhi
<manaf.pallikunhi@oss.qualcomm.com>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
Bjorn Andersson <andersson@kernel.org>,
Konrad Dybcio <konradybcio@kernel.org>,
Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
Cc: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>,
linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org
Subject: Re: [PATCH v2 2/3] powercap: qcom: Add SPEL powercap driver
Date: Mon, 22 Jun 2026 13:01:39 +0200 [thread overview]
Message-ID: <e203221b-5de5-4cc3-b65a-a3545986a954@oss.qualcomm.com> (raw)
In-Reply-To: <20260620-qcom_spel_driver_upstream-v2-2-a3ee6837c18f@oss.qualcomm.com>
On 6/19/26 10:39 PM, Manaf Meethalavalappu Pallikunhi wrote:
> The Qualcomm SoC Power and Electrical Limits (SPEL) provides hardware
> based power monitoring and limiting capabilities for various power
> domains including System, SoC, CPU clusters, GPU, and various other
> subsystems.
>
> The driver integrates with the Linux powercap framework, exposing SPEL
> capabilities through powercap sysfs interfaces.
>
> Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
> ---
[...]
> +#include <linux/bitfield.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/mutex.h>
> +#include <linux/platform_device.h>
> +#include <linux/powercap.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
Please ensure all the includes are necessary
> +
> +/* SPEL register bitmasks */
> +#define ENERGY_STATUS_MASK GENMASK(31, 0)
> +
> +#define POWER_LIMIT_MASK GENMASK(14, 0)
> +#define POWER_LIMIT_ENABLE BIT(31)
> +
> +#define TIME_WINDOW_MASK_L GENMASK(14, 0)
> +#define TIME_WINDOW_MASK_H GENMASK(22, 16)
Is BIT(15) not part of this?
[...]
> +/* Domain configuration */
> +static const struct spel_domain_info domain_info[SPEL_DOMAIN_MAX] = {
> + [SPEL_DOMAIN_SYS] = { "sys", 0x40 },
> + [SPEL_DOMAIN_SOC] = { "soc", 0x00 },
> + [SPEL_DOMAIN_CL0] = { "cl0", 0x5c },
> + [SPEL_DOMAIN_CL1] = { "cl1", 0x60 },
> + [SPEL_DOMAIN_CL2] = { "cl2", 0x64 },
> + [SPEL_DOMAIN_IGPU] = { "igpu", 0x08 },
> + [SPEL_DOMAIN_DGPU] = { "dgpu", 0x44 },
> + [SPEL_DOMAIN_NSP] = { "nsp", 0x0c },
> + [SPEL_DOMAIN_MMCX] = { "mmcx", 0x10 },
> + [SPEL_DOMAIN_INFRA] = { "infra", 0x18 },
> + [SPEL_DOMAIN_DRAM] = { "dram", 0x1c },
> + [SPEL_DOMAIN_MDM] = { "mdm", 0x48 },
> + [SPEL_DOMAIN_WLAN] = { "wlan", 0x4c },
> + [SPEL_DOMAIN_USB1] = { "usb1", 0x50 },
> + [SPEL_DOMAIN_USB2] = { "usb2", 0x54 },
> + [SPEL_DOMAIN_USB3] = { "usb3", 0x58 },
> +};
I would expect that the names are going to stay common, but the offsets
will be different. This array should probably be called
glymur_domain_info[]. We may have another LUT just for names of indices
(i.e. [SPEL_DOMAIN_xxx] = "xxx")
> +
> +/**
> + * struct spel_constraint_info - Power limit constraint information
> + * @limit_offset: Register offset for power limit value
> + * @time_window_offset: Register offset for time window
> + * @supported_mask: Bit mask in capability register
> + * @domain_id: Domain this constraint applies to
> + * @pl_id: Power limit ID (PL1, PL2, etc.)
> + */
> +struct spel_constraint_info {
> + u32 limit_offset;
> + u32 time_window_offset;
> + u32 supported_mask;
> + enum spel_domain_type domain_id;
> + int pl_id;
> +};
> +
> +/* Constraint configuration */
> +static const struct spel_constraint_info constraints[] = {
> + /* SYS domain constraints */
> + { 0x10, 0x70, BIT(0), SPEL_DOMAIN_SYS, POWER_LIMIT1 },
> + { 0x14, 0x74, BIT(1), SPEL_DOMAIN_SYS, POWER_LIMIT2 },
> + { 0x18, 0x78, BIT(2), SPEL_DOMAIN_SYS, POWER_LIMIT3 },
> + { 0x1c, 0x7c, BIT(3), SPEL_DOMAIN_SYS, POWER_LIMIT4 },
> + /* SoC domain constraints */
> + { 0x00, 0x60, BIT(4), SPEL_DOMAIN_SOC, POWER_LIMIT1 },
> + { 0x04, 0x64, BIT(5), SPEL_DOMAIN_SOC, POWER_LIMIT2 },
> + { 0x08, 0x68, BIT(6), SPEL_DOMAIN_SOC, POWER_LIMIT3 },
> + { 0x0c, 0x6c, BIT(7), SPEL_DOMAIN_SOC, POWER_LIMIT4 },
> +};
Is this specific to Glymur, or SPEL-wide?
[...]
> +/**
> + * struct spel_system - SPEL system
odd tab after '-'
[...]
> + case PL_LIMIT:
> + new_val = spel_unit_xlate(sd, POWER_UNIT, value, 1);
> + if (new_val > FIELD_MAX(POWER_LIMIT_MASK))
> + return -EINVAL;
> + reg_val = (reg_val & ~POWER_LIMIT_MASK) | FIELD_PREP(POWER_LIMIT_MASK, new_val);
FIELD_MODIFY()
> +
> + /*
> + * Enable/Disable PL based on the value:
> + * - If value is 0, disable the PL (clear enable bit)
> + * - If value is non-zero, enable the PL (set enable bit)
> + */
> + if (new_val == 0)
> + reg_val &= ~POWER_LIMIT_ENABLE;
> + else
> + reg_val |= POWER_LIMIT_ENABLE;
Likewise
> +
> + writel(reg_val, reg_addr);
> + return 0;
> +
> + case PL_TIME_WINDOW:
> + /*
> + * Encode time window: upper 7 bits to [22:16], lower 15 bits to [14:0]
> + */
> + new_val = spel_unit_xlate(sd, TIME_UNIT, value, 1);
> + if (new_val > TIME_WINDOW_MAX)
> + return -EINVAL;
> + /* Read-modify-write to preserve other bits */
> + reg_val = (reg_val & ~(TIME_WINDOW_MASK_H | TIME_WINDOW_MASK_L)) |
> + FIELD_PREP(TIME_WINDOW_MASK_H, new_val >> 15) |
> + FIELD_PREP(TIME_WINDOW_MASK_L, new_val);
Also here
[...]
> +static void spel_detect_powerlimit(struct spel_domain *sd)
> +{
> + struct spel_system *sp = sd->sp;
> + u32 capabilities;
> + int i, j;
> +
> + capabilities = readl(sp->config_base + LIMITS_CAPABILITY_OFFSET);
> +
> + /*
> + * Detect power limits from hardware capabilities.
> + * Start from index 1 (POWER_LIMIT2) since PL1 is always enabled in spel_init_domains().
> + */
> + for (i = 1; i < ARRAY_SIZE(pl_names); i++) {
int i = POWER_LIMIT2
(yeah, nowadays you can finally declare the iterator inside the loop
in the kernel)
Konrad
next prev parent reply other threads:[~2026-06-22 11:01 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-19 20:39 [PATCH v2 0/3] Add Qualcomm " Manaf Meethalavalappu Pallikunhi
2026-06-19 20:39 ` [PATCH v2 1/3] dt-bindings: power: limits: Describe Qualcomm SPEL hardware Manaf Meethalavalappu Pallikunhi
2026-06-22 11:02 ` Konrad Dybcio
2026-06-22 15:11 ` Manaf Meethalavalappu Pallikunhi
2026-06-22 12:28 ` Krzysztof Kozlowski
2026-06-23 9:47 ` Manaf Meethalavalappu Pallikunhi
2026-06-24 10:45 ` Krzysztof Kozlowski
2026-06-24 20:41 ` Daniel Lezcano
2026-06-25 6:45 ` Krzysztof Kozlowski
2026-06-19 20:39 ` [PATCH v2 2/3] powercap: qcom: Add SPEL powercap driver Manaf Meethalavalappu Pallikunhi
2026-06-22 11:01 ` Konrad Dybcio [this message]
2026-06-23 10:58 ` Manaf Meethalavalappu Pallikunhi
2026-06-23 11:11 ` Konrad Dybcio
2026-06-19 20:39 ` [PATCH v2 3/3] arm64: dts: qcom: glymur: Enable " Manaf Meethalavalappu Pallikunhi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e203221b-5de5-4cc3-b65a-a3545986a954@oss.qualcomm.com \
--to=konrad.dybcio@oss.qualcomm.com \
--cc=andersson@kernel.org \
--cc=conor+dt@kernel.org \
--cc=daniel.lezcano@oss.qualcomm.com \
--cc=devicetree@vger.kernel.org \
--cc=gaurav.kohli@oss.qualcomm.com \
--cc=konradybcio@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=manaf.pallikunhi@oss.qualcomm.com \
--cc=rafael@kernel.org \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®