Skip to content

Commit 8aa7306

Browse files
kpoosarodrigovivi
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: 7596d83 ("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]>
1 parent bcc2872 commit 8aa7306

File tree

2 files changed

+24
-27
lines changed

2 files changed

+24
-27
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: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ static int xe_hwmon_pcode_read_power_limit(const struct xe_hwmon *hwmon, u32 att
175175
return ret;
176176
}
177177

178-
static int xe_hwmon_pcode_write_power_limit(const struct xe_hwmon *hwmon, u32 attr, u8 channel,
179-
u32 uval)
178+
static int xe_hwmon_pcode_rmw_power_limit(const struct xe_hwmon *hwmon, u32 attr, u8 channel,
179+
u32 clr, u32 set)
180180
{
181181
struct xe_tile *root_tile = xe_device_get_root_tile(hwmon->xe);
182182
u32 val0, val1;
@@ -195,9 +195,9 @@ static int xe_hwmon_pcode_write_power_limit(const struct xe_hwmon *hwmon, u32 at
195195
channel, val0, val1, ret);
196196

197197
if (attr == PL1_HWMON_ATTR)
198-
val0 = uval;
198+
val0 = (val0 & ~clr) | set;
199199
else if (attr == PL2_HWMON_ATTR)
200-
val1 = uval;
200+
val1 = (val1 & ~clr) | set;
201201
else
202202
return -EIO;
203203

@@ -342,7 +342,7 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channe
342342
if (hwmon->xe->info.has_mbx_power_limits) {
343343
drm_dbg(&hwmon->xe->drm, "disabling %s on channel %d\n",
344344
PWR_ATTR_TO_STR(attr), channel);
345-
xe_hwmon_pcode_write_power_limit(hwmon, attr, channel, 0);
345+
xe_hwmon_pcode_rmw_power_limit(hwmon, attr, channel, PWR_LIM_EN, 0);
346346
xe_hwmon_pcode_read_power_limit(hwmon, attr, channel, &reg_val);
347347
} else {
348348
reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM_EN, 0);
@@ -378,10 +378,9 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channe
378378
reg_val = PWR_LIM_EN | REG_FIELD_PREP(PWR_LIM_VAL, reg_val);
379379

380380
if (hwmon->xe->info.has_mbx_power_limits)
381-
ret = xe_hwmon_pcode_write_power_limit(hwmon, attr, channel, reg_val);
381+
ret = xe_hwmon_pcode_rmw_power_limit(hwmon, attr, channel, PWR_LIM, reg_val);
382382
else
383-
reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM_EN | PWR_LIM_VAL,
384-
reg_val);
383+
reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM, reg_val);
385384
unlock:
386385
mutex_unlock(&hwmon->hwmon_lock);
387386
return ret;
@@ -591,14 +590,11 @@ xe_hwmon_power_max_interval_store(struct device *dev, struct device_attribute *a
591590

592591
mutex_lock(&hwmon->hwmon_lock);
593592

594-
if (hwmon->xe->info.has_mbx_power_limits) {
595-
ret = xe_hwmon_pcode_read_power_limit(hwmon, power_attr, channel, (u32 *)&r);
596-
r = (r & ~PWR_LIM_TIME) | rxy;
597-
xe_hwmon_pcode_write_power_limit(hwmon, power_attr, channel, r);
598-
} else {
593+
if (hwmon->xe->info.has_mbx_power_limits)
594+
xe_hwmon_pcode_rmw_power_limit(hwmon, power_attr, channel, PWR_LIM_TIME, rxy);
595+
else
599596
r = xe_mmio_rmw32(mmio, xe_hwmon_get_reg(hwmon, REG_PKG_RAPL_LIMIT, channel),
600597
PWR_LIM_TIME, rxy);
601-
}
602598

603599
mutex_unlock(&hwmon->hwmon_lock);
604600

@@ -1217,25 +1213,25 @@ xe_hwmon_get_preregistration_info(struct xe_hwmon *hwmon)
12171213
&hwmon->pl1_on_boot[CHANNEL_PKG]) |
12181214
xe_hwmon_pcode_read_power_limit(hwmon, PL2_HWMON_ATTR, CHANNEL_CARD,
12191215
&hwmon->pl2_on_boot[CHANNEL_CARD]) |
1220-
xe_hwmon_pcode_read_power_limit(hwmon, PL1_HWMON_ATTR, CHANNEL_PKG,
1216+
xe_hwmon_pcode_read_power_limit(hwmon, PL2_HWMON_ATTR, CHANNEL_PKG,
12211217
&hwmon->pl2_on_boot[CHANNEL_PKG])) {
12221218
drm_warn(&hwmon->xe->drm,
12231219
"Failed to read power limits, check GPU firmware !\n");
12241220
} else {
12251221
drm_info(&hwmon->xe->drm, "Using mailbox commands for power limits\n");
12261222
/* Write default limits to read from pcode from now on. */
1227-
xe_hwmon_pcode_write_power_limit(hwmon, PL1_HWMON_ATTR,
1228-
CHANNEL_CARD,
1229-
hwmon->pl1_on_boot[CHANNEL_CARD]);
1230-
xe_hwmon_pcode_write_power_limit(hwmon, PL1_HWMON_ATTR,
1231-
CHANNEL_PKG,
1232-
hwmon->pl1_on_boot[CHANNEL_PKG]);
1233-
xe_hwmon_pcode_write_power_limit(hwmon, PL2_HWMON_ATTR,
1234-
CHANNEL_CARD,
1235-
hwmon->pl2_on_boot[CHANNEL_CARD]);
1236-
xe_hwmon_pcode_write_power_limit(hwmon, PL2_HWMON_ATTR,
1237-
CHANNEL_PKG,
1238-
hwmon->pl2_on_boot[CHANNEL_PKG]);
1223+
xe_hwmon_pcode_rmw_power_limit(hwmon, PL1_HWMON_ATTR,
1224+
CHANNEL_CARD, PWR_LIM | PWR_LIM_TIME,
1225+
hwmon->pl1_on_boot[CHANNEL_CARD]);
1226+
xe_hwmon_pcode_rmw_power_limit(hwmon, PL1_HWMON_ATTR,
1227+
CHANNEL_PKG, PWR_LIM | PWR_LIM_TIME,
1228+
hwmon->pl1_on_boot[CHANNEL_PKG]);
1229+
xe_hwmon_pcode_rmw_power_limit(hwmon, PL2_HWMON_ATTR,
1230+
CHANNEL_CARD, PWR_LIM | PWR_LIM_TIME,
1231+
hwmon->pl2_on_boot[CHANNEL_CARD]);
1232+
xe_hwmon_pcode_rmw_power_limit(hwmon, PL2_HWMON_ATTR,
1233+
CHANNEL_PKG, PWR_LIM | PWR_LIM_TIME,
1234+
hwmon->pl2_on_boot[CHANNEL_PKG]);
12391235
hwmon->scl_shift_power = PWR_UNIT;
12401236
hwmon->scl_shift_energy = ENERGY_UNIT;
12411237
hwmon->scl_shift_time = TIME_UNIT;

0 commit comments

Comments
 (0)