Skip to content

Commit 9127a69

Browse files
kpoosaThomas Hellström
authored andcommitted
drm/xe/hwmon: Fix xe_hwmon_power_max_write
Prevent other bits of mailbox power limit from being overwritten with 0. This issue was due to a missing read and modify of current power limit, before setting a requested mailbox power limit, which is added in this patch. v2: - Improve commit message. (Anshuman) v3: - Rebase. - Rephrase commit message. (Riana) - Add read-modify-write variant of xe_hwmon_pcode_write_power_limit() i.e. xe_hwmon_pcode_rmw_power_limit(). (Badal) - Use xe_hwmon_pcode_rmw_power_limit() to set mailbox power limits. - Remove xe_hwmon_pcode_write_power_limit() as all mailbox power limits writes use xe_hwmon_pcode_rmw_power_limit() only. v4: - Use PWR_LIM in place of (PWR_LIM_EN | PWR_LIM_VAL) wherever applicable. (Riana) Fixes: 25a2aa7 ("drm/xe/hwmon: Add support to manage power limits though mailbox") Reviewed-by: Riana Tauro <[email protected]> Signed-off-by: Karthik Poosa <[email protected]> Reviewed-by: Badal Nilawar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Rodrigo Vivi <[email protected]> (cherry picked from commit 8aa7306) Signed-off-by: Thomas Hellström <[email protected]>
1 parent 6220729 commit 9127a69

File tree

2 files changed

+16
-19
lines changed

2 files changed

+16
-19
lines changed

drivers/gpu/drm/xe/regs/xe_mchbar_regs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#define PCU_CR_PACKAGE_RAPL_LIMIT XE_REG(MCHBAR_MIRROR_BASE_SNB + 0x59a0)
4141
#define PWR_LIM_VAL REG_GENMASK(14, 0)
4242
#define PWR_LIM_EN REG_BIT(15)
43+
#define PWR_LIM REG_GENMASK(15, 0)
4344
#define PWR_LIM_TIME REG_GENMASK(23, 17)
4445
#define PWR_LIM_TIME_X REG_GENMASK(23, 22)
4546
#define PWR_LIM_TIME_Y REG_GENMASK(21, 17)

drivers/gpu/drm/xe/xe_hwmon.c

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ static int xe_hwmon_pcode_read_power_limit(const struct xe_hwmon *hwmon, u32 att
159159
return ret;
160160
}
161161

162-
static int xe_hwmon_pcode_write_power_limit(const struct xe_hwmon *hwmon, u32 attr, u8 channel,
163-
u32 uval)
162+
static int xe_hwmon_pcode_rmw_power_limit(const struct xe_hwmon *hwmon, u32 attr, u8 channel,
163+
u32 clr, u32 set)
164164
{
165165
struct xe_tile *root_tile = xe_device_get_root_tile(hwmon->xe);
166166
u32 val0, val1;
@@ -179,7 +179,7 @@ static int xe_hwmon_pcode_write_power_limit(const struct xe_hwmon *hwmon, u32 at
179179
channel, val0, val1, ret);
180180

181181
if (attr == PL1_HWMON_ATTR)
182-
val0 = uval;
182+
val0 = (val0 & ~clr) | set;
183183
else
184184
return -EIO;
185185

@@ -339,7 +339,7 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channe
339339
if (hwmon->xe->info.has_mbx_power_limits) {
340340
drm_dbg(&hwmon->xe->drm, "disabling %s on channel %d\n",
341341
PWR_ATTR_TO_STR(attr), channel);
342-
xe_hwmon_pcode_write_power_limit(hwmon, attr, channel, 0);
342+
xe_hwmon_pcode_rmw_power_limit(hwmon, attr, channel, PWR_LIM_EN, 0);
343343
xe_hwmon_pcode_read_power_limit(hwmon, attr, channel, &reg_val);
344344
} else {
345345
reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM_EN, 0);
@@ -370,10 +370,9 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channe
370370
}
371371

372372
if (hwmon->xe->info.has_mbx_power_limits)
373-
ret = xe_hwmon_pcode_write_power_limit(hwmon, attr, channel, reg_val);
373+
ret = xe_hwmon_pcode_rmw_power_limit(hwmon, attr, channel, PWR_LIM, reg_val);
374374
else
375-
reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM_EN | PWR_LIM_VAL,
376-
reg_val);
375+
reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM, reg_val);
377376
unlock:
378377
mutex_unlock(&hwmon->hwmon_lock);
379378
return ret;
@@ -563,14 +562,11 @@ xe_hwmon_power_max_interval_store(struct device *dev, struct device_attribute *a
563562

564563
mutex_lock(&hwmon->hwmon_lock);
565564

566-
if (hwmon->xe->info.has_mbx_power_limits) {
567-
ret = xe_hwmon_pcode_read_power_limit(hwmon, power_attr, channel, (u32 *)&r);
568-
r = (r & ~PWR_LIM_TIME) | rxy;
569-
xe_hwmon_pcode_write_power_limit(hwmon, power_attr, channel, r);
570-
} else {
565+
if (hwmon->xe->info.has_mbx_power_limits)
566+
xe_hwmon_pcode_rmw_power_limit(hwmon, power_attr, channel, PWR_LIM_TIME, rxy);
567+
else
571568
r = xe_mmio_rmw32(mmio, xe_hwmon_get_reg(hwmon, REG_PKG_RAPL_LIMIT, channel),
572569
PWR_LIM_TIME, rxy);
573-
}
574570

575571
mutex_unlock(&hwmon->hwmon_lock);
576572

@@ -1138,12 +1134,12 @@ xe_hwmon_get_preregistration_info(struct xe_hwmon *hwmon)
11381134
} else {
11391135
drm_info(&hwmon->xe->drm, "Using mailbox commands for power limits\n");
11401136
/* Write default limits to read from pcode from now on. */
1141-
xe_hwmon_pcode_write_power_limit(hwmon, PL1_HWMON_ATTR,
1142-
CHANNEL_CARD,
1143-
hwmon->pl1_on_boot[CHANNEL_CARD]);
1144-
xe_hwmon_pcode_write_power_limit(hwmon, PL1_HWMON_ATTR,
1145-
CHANNEL_PKG,
1146-
hwmon->pl1_on_boot[CHANNEL_PKG]);
1137+
xe_hwmon_pcode_rmw_power_limit(hwmon, PL1_HWMON_ATTR,
1138+
CHANNEL_CARD, PWR_LIM | PWR_LIM_TIME,
1139+
hwmon->pl1_on_boot[CHANNEL_CARD]);
1140+
xe_hwmon_pcode_rmw_power_limit(hwmon, PL1_HWMON_ATTR,
1141+
CHANNEL_PKG, PWR_LIM | PWR_LIM_TIME,
1142+
hwmon->pl1_on_boot[CHANNEL_PKG]);
11471143
hwmon->scl_shift_power = PWR_UNIT;
11481144
hwmon->scl_shift_energy = ENERGY_UNIT;
11491145
hwmon->scl_shift_time = TIME_UNIT;

0 commit comments

Comments
 (0)