Update the HFI definitions to support additional GMU based power
features.
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 3 -
drivers/gpu/drm/msm/adreno/a6xx_hfi.h | 113 +++++++++++++++++++++++++++++++++-
2 files changed, 111 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c
index aef00c2dd137..d613bf00e3f8 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c
@@ -851,7 +851,6 @@ static int a6xx_hfi_feature_ctrl_msg(struct a6xx_gmu *gmu, u32 feature, u32 enab
return a6xx_hfi_send_msg(gmu, HFI_H2F_FEATURE_CTRL, &msg, sizeof(msg), NULL, 0);
}
-#define HFI_FEATURE_IFPC 9
#define IFPC_LONG_HYST 0x1680
static int a6xx_hfi_enable_ifpc(struct a6xx_gmu *gmu)
@@ -862,8 +861,6 @@ static int a6xx_hfi_enable_ifpc(struct a6xx_gmu *gmu)
return a6xx_hfi_feature_ctrl_msg(gmu, HFI_FEATURE_IFPC, 1, IFPC_LONG_HYST);
}
-#define HFI_FEATURE_ACD 12
-
static int a6xx_hfi_enable_acd(struct a6xx_gmu *gmu)
{
struct a6xx_hfi_acd_table *acd_table = &gmu->acd_table;
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.h b/drivers/gpu/drm/msm/adreno/a6xx_hfi.h
index 217708b03f6f..917b9c9e9906 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.h
@@ -165,6 +165,42 @@ struct a6xx_hfi_acd_table {
u32 data[16 * MAX_ACD_STRIDE];
} __packed;
+#define CLX_DATA(irated, num_phases, clx_path, extd_intf) \
+ ((extd_intf << 29) | \
+ (clx_path << 28) | \
+ (num_phases << 22) | \
+ (irated << 16))
+
+struct a6xx_hfi_clx_domain_v2 {
+ /**
+ * @data: BITS[0:15] Migration time
+ * BITS[16:21] Current rating
+ * BITS[22:27] Phases for domain
+ * BITS[28:28] Path notification
+ * BITS[29:31] Extra features
+ */
+ u32 data;
+ /** @clxt: CLX time in microseconds */
+ u32 clxt;
+ /** @clxh: CLH time in microseconds */
+ u32 clxh;
+ /** @urg_mode: Urgent HW throttle mode of operation */
+ u32 urg_mode;
+ /** @lkg_en: Enable leakage current estimate */
+ u32 lkg_en;
+ /** curr_budget: Current Budget */
+ u32 curr_budget;
+} __packed;
+
+#define HFI_H2F_MSG_CLX_TBL 8
+
+#define MAX_CLX_DOMAINS 2
+struct a6xx_hfi_clx_table_v2_cmd {
+ u32 hdr;
+ u32 version;
+ struct a6xx_hfi_clx_domain_v2 domain[MAX_CLX_DOMAINS];
+} __packed;
+
#define HFI_H2F_MSG_START 10
struct a6xx_hfi_msg_start {
@@ -176,6 +212,41 @@ struct a6xx_hfi_msg_start {
struct a6xx_hfi_msg_feature_ctrl {
u32 header;
u32 feature;
+#define HFI_FEATURE_DCVS 0
+#define HFI_FEATURE_HWSCHED 1
+#define HFI_FEATURE_PREEMPTION 2
+#define HFI_FEATURE_CLOCKS_ON 3
+#define HFI_FEATURE_BUS_ON 4
+#define HFI_FEATURE_RAIL_ON 5
+#define HFI_FEATURE_HWCG 6
+#define HFI_FEATURE_LM 7
+#define HFI_FEATURE_THROTTLE 8
+#define HFI_FEATURE_IFPC 9
+#define HFI_FEATURE_NAP 10
+#define HFI_FEATURE_BCL 11
+#define HFI_FEATURE_ACD 12
+#define HFI_FEATURE_DIDT 13
+#define HFI_FEATURE_DEPRECATED 14
+#define HFI_FEATURE_CB 15
+#define HFI_FEATURE_KPROF 16
+#define HFI_FEATURE_BAIL_OUT_TIMER 17
+#define HFI_FEATURE_GMU_STATS 18
+#define HFI_FEATURE_DBQ 19
+#define HFI_FEATURE_MINBW 20
+#define HFI_FEATURE_CLX 21
+#define HFI_FEATURE_LSR 23
+#define HFI_FEATURE_LPAC 24
+#define HFI_FEATURE_HW_FENCE 25
+#define HFI_FEATURE_PERF_NORETAIN 26
+#define HFI_FEATURE_DMS 27
+#define HFI_FEATURE_THERMAL 28
+#define HFI_FEATURE_AQE 29
+#define HFI_FEATURE_TDCVS 30
+#define HFI_FEATURE_DCE 31
+#define HFI_FEATURE_IFF_PCLX 32
+#define HFI_FEATURE_SOFT_RESET 0x10000001
+#define HFI_FEATURE_DCVS_PROFILE 0x10000002
+#define HFI_FEATURE_FAST_CTX_DESTROY 0x10000003
u32 enable;
u32 data;
} __packed;
@@ -199,8 +270,17 @@ struct a6xx_hfi_table {
u32 header;
u32 version;
u32 type;
-#define HFI_TABLE_BW_VOTE 0
-#define HFI_TABLE_GPU_PERF 1
+#define HFI_TABLE_BW_VOTE 0
+#define HFI_TABLE_GPU_PERF 1
+#define HFI_TABLE_DIDT 2
+#define HFI_TABLE_ACD 3
+#define HFI_TABLE_CLX_V1 4 /* Unused */
+#define HFI_TABLE_CLX_V2 5
+#define HFI_TABLE_THERM 6
+#define HFI_TABLE_DCVS 7
+#define HFI_TABLE_SYS_TIME 8
+#define HFI_TABLE_GMU_DCVS 9
+#define HFI_TABLE_LIMITS_MIT 10
struct a6xx_hfi_table_entry entry[];
} __packed;
@@ -226,4 +306,33 @@ struct a6xx_hfi_prep_slumber_cmd {
u32 freq;
} __packed;
+struct a6xx_hfi_limits_cfg {
+ u32 enable;
+ u32 msg_path;
+ u32 lkg_en;
+ /**
+ * @mode: BIT[0]: 0 = (static) throttle to fixed sid level
+ * 1 = (dynamic) throttle to sid lievel calculated by HW
+ * BIT[1]: 0 = Mx
+ * 1 = Bx
+ */
+ u32 mode;
+ u32 sid;
+ /** @mit_time: mitigation time in microseconds */
+ u32 mit_time;
+ /** @curr_limit: Max current in mA during mitigation */
+ u32 curr_limit;
+} __packed;
+
+struct a6xx_hfi_limits_tbl {
+ u8 feature_id;
+#define GMU_MIT_IFF 0
+#define GMU_MIT_PCLX 1
+ u8 domain;
+#define GMU_GX_DOMAIN 0
+#define GMU_MX_DOMAIN 1
+ u16 feature_rev;
+ struct a6xx_hfi_limits_cfg cfg;
+} __packed;
+
#endif
--
2.51.0
On 3/23/26 9:12 PM, Akhil P Oommen wrote:
> Update the HFI definitions to support additional GMU based power
> features.
>
> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
> ---
[...]
> +#define CLX_DATA(irated, num_phases, clx_path, extd_intf) \
> + ((extd_intf << 29) | \
> + (clx_path << 28) | \
> + (num_phases << 22) | \
> + (irated << 16))
> +
> +struct a6xx_hfi_clx_domain_v2 {
> + /**
> + * @data: BITS[0:15] Migration time
> + * BITS[16:21] Current rating
> + * BITS[22:27] Phases for domain
> + * BITS[28:28] Path notification
> + * BITS[29:31] Extra features
> + */
My first thought would be to define these as bitfields, i.e.
u16 mitigation_time
u8 current_rating : 6;
u8 num_phases : 6;
u8 path_notification : 1;
u8 extra_features : 3;
(hopefully I counted them right)
You would then not need custom macros to set/get the data
> + u32 data;
> + /** @clxt: CLX time in microseconds */
slash-star-star implies kerneldoc, which this isn't - but it would
be appreciated, see e.g. struct qcom_icc_provider in
drivers/interconnect/qcom/icc-rpmh.h
Konrad
On 3/24/2026 3:30 PM, Konrad Dybcio wrote:
> On 3/23/26 9:12 PM, Akhil P Oommen wrote:
>> Update the HFI definitions to support additional GMU based power
>> features.
>>
>> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
>> ---
>
> [...]
>
>> +#define CLX_DATA(irated, num_phases, clx_path, extd_intf) \
>> + ((extd_intf << 29) | \
>> + (clx_path << 28) | \
>> + (num_phases << 22) | \
>> + (irated << 16))
>> +
>> +struct a6xx_hfi_clx_domain_v2 {
>> + /**
>> + * @data: BITS[0:15] Migration time
>> + * BITS[16:21] Current rating
>> + * BITS[22:27] Phases for domain
>> + * BITS[28:28] Path notification
>> + * BITS[29:31] Extra features
>> + */
>
> My first thought would be to define these as bitfields, i.e.
> u16 mitigation_time
> u8 current_rating : 6;
> u8 num_phases : 6;
> u8 path_notification : 1;
> u8 extra_features : 3;
>
I am unsure if the compiler would mess with the ordering. Aside from the
fact that this is an ABI with the firmware, what make this piece of data
very risk is that, these are power related configurations where the
issues due to misconfiguration won't be immediately obvious.
-Akhil.
> (hopefully I counted them right)
>
> You would then not need custom macros to set/get the data
>
>> + u32 data;
>> + /** @clxt: CLX time in microseconds */
>
> slash-star-star implies kerneldoc, which this isn't - but it would
> be appreciated, see e.g. struct qcom_icc_provider in
> drivers/interconnect/qcom/icc-rpmh.h
>
> Konrad
On 3/26/26 6:47 PM, Akhil P Oommen wrote:
> On 3/24/2026 3:30 PM, Konrad Dybcio wrote:
>> On 3/23/26 9:12 PM, Akhil P Oommen wrote:
>>> Update the HFI definitions to support additional GMU based power
>>> features.
>>>
>>> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
>>> ---
>>
>> [...]
>>
>>> +#define CLX_DATA(irated, num_phases, clx_path, extd_intf) \
>>> + ((extd_intf << 29) | \
>>> + (clx_path << 28) | \
>>> + (num_phases << 22) | \
>>> + (irated << 16))
>>> +
>>> +struct a6xx_hfi_clx_domain_v2 {
>>> + /**
>>> + * @data: BITS[0:15] Migration time
>>> + * BITS[16:21] Current rating
>>> + * BITS[22:27] Phases for domain
>>> + * BITS[28:28] Path notification
>>> + * BITS[29:31] Extra features
>>> + */
>>
>> My first thought would be to define these as bitfields, i.e.
>> u16 mitigation_time
>> u8 current_rating : 6;
>> u8 num_phases : 6;
>> u8 path_notification : 1;
>> u8 extra_features : 3;
>>
>
> I am unsure if the compiler would mess with the ordering. Aside from the
> fact that this is an ABI with the firmware, what make this piece of data
> very risk is that, these are power related configurations where the
> issues due to misconfiguration won't be immediately obvious.
These are two fully equivalent ways of representing the same data.
The compiler won't reorder them, since data in structs is.. stuctured..
In any case, either of them is fine. The struct definition would be more
convenient to work with if the data was provided in C code, whereas I can
see the simple-u32 being more convenient if it's going to be pulled from
the DTS
Konrad
© 2016 - 2026 Red Hat, Inc.