955 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2022 Intel Corporation4 */5 6#include <linux/hwmon.h>7#include <linux/hwmon-sysfs.h>8#include <linux/jiffies.h>9#include <linux/types.h>10 11#include "i915_drv.h"12#include "i915_hwmon.h"13#include "i915_reg.h"14#include "intel_mchbar_regs.h"15#include "intel_pcode.h"16#include "gt/intel_gt.h"17#include "gt/intel_gt_regs.h"18 19/*20 * SF_* - scale factors for particular quantities according to hwmon spec.21 * - voltage - millivolts22 * - power - microwatts23 * - curr - milliamperes24 * - energy - microjoules25 * - time - milliseconds26 */27#define SF_VOLTAGE 100028#define SF_POWER 100000029#define SF_CURR 100030#define SF_ENERGY 100000031#define SF_TIME 100032 33struct hwm_reg {34 i915_reg_t gt_perf_status;35 i915_reg_t pkg_power_sku_unit;36 i915_reg_t pkg_power_sku;37 i915_reg_t pkg_rapl_limit;38 i915_reg_t energy_status_all;39 i915_reg_t energy_status_tile;40 i915_reg_t fan_speed;41};42 43struct hwm_energy_info {44 u32 reg_val_prev;45 long accum_energy; /* Accumulated energy for energy1_input */46};47 48struct hwm_fan_info {49 u32 reg_val_prev;50 u64 time_prev;51};52 53struct hwm_drvdata {54 struct i915_hwmon *hwmon;55 struct intel_uncore *uncore;56 struct device *hwmon_dev;57 struct hwm_energy_info ei; /* Energy info for energy1_input */58 struct hwm_fan_info fi; /* Fan info for fan1_input */59 char name[12];60 int gt_n;61 bool reset_in_progress;62 wait_queue_head_t waitq;63};64 65struct i915_hwmon {66 struct hwm_drvdata ddat;67 struct hwm_drvdata ddat_gt[I915_MAX_GT];68 struct mutex hwmon_lock; /* counter overflow logic and rmw */69 struct hwm_reg rg;70 int scl_shift_power;71 int scl_shift_energy;72 int scl_shift_time;73};74 75static void76hwm_locked_with_pm_intel_uncore_rmw(struct hwm_drvdata *ddat,77 i915_reg_t reg, u32 clear, u32 set)78{79 struct i915_hwmon *hwmon = ddat->hwmon;80 struct intel_uncore *uncore = ddat->uncore;81 intel_wakeref_t wakeref;82 83 with_intel_runtime_pm(uncore->rpm, wakeref) {84 mutex_lock(&hwmon->hwmon_lock);85 86 intel_uncore_rmw(uncore, reg, clear, set);87 88 mutex_unlock(&hwmon->hwmon_lock);89 }90}91 92/*93 * This function's return type of u64 allows for the case where the scaling94 * of the field taken from the 32-bit register value might cause a result to95 * exceed 32 bits.96 */97static u6498hwm_field_read_and_scale(struct hwm_drvdata *ddat, i915_reg_t rgadr,99 u32 field_msk, int nshift, u32 scale_factor)100{101 struct intel_uncore *uncore = ddat->uncore;102 intel_wakeref_t wakeref;103 u32 reg_value;104 105 with_intel_runtime_pm(uncore->rpm, wakeref)106 reg_value = intel_uncore_read(uncore, rgadr);107 108 reg_value = REG_FIELD_GET(field_msk, reg_value);109 110 return mul_u64_u32_shr(reg_value, scale_factor, nshift);111}112 113/*114 * hwm_energy - Obtain energy value115 *116 * The underlying energy hardware register is 32-bits and is subject to117 * overflow. How long before overflow? For example, with an example118 * scaling bit shift of 14 bits (see register *PACKAGE_POWER_SKU_UNIT) and119 * a power draw of 1000 watts, the 32-bit counter will overflow in120 * approximately 4.36 minutes.121 *122 * Examples:123 * 1 watt: (2^32 >> 14) / 1 W / (60 * 60 * 24) secs/day -> 3 days124 * 1000 watts: (2^32 >> 14) / 1000 W / 60 secs/min -> 4.36 minutes125 *126 * The function significantly increases overflow duration (from 4.36127 * minutes) by accumulating the energy register into a 'long' as allowed by128 * the hwmon API. Using x86_64 128 bit arithmetic (see mul_u64_u32_shr()),129 * a 'long' of 63 bits, SF_ENERGY of 1e6 (~20 bits) and130 * hwmon->scl_shift_energy of 14 bits we have 57 (63 - 20 + 14) bits before131 * energy1_input overflows. This at 1000 W is an overflow duration of 278 years.132 */133static void134hwm_energy(struct hwm_drvdata *ddat, long *energy)135{136 struct intel_uncore *uncore = ddat->uncore;137 struct i915_hwmon *hwmon = ddat->hwmon;138 struct hwm_energy_info *ei = &ddat->ei;139 intel_wakeref_t wakeref;140 i915_reg_t rgaddr;141 u32 reg_val;142 143 if (ddat->gt_n >= 0)144 rgaddr = hwmon->rg.energy_status_tile;145 else146 rgaddr = hwmon->rg.energy_status_all;147 148 with_intel_runtime_pm(uncore->rpm, wakeref) {149 mutex_lock(&hwmon->hwmon_lock);150 151 reg_val = intel_uncore_read(uncore, rgaddr);152 153 if (reg_val >= ei->reg_val_prev)154 ei->accum_energy += reg_val - ei->reg_val_prev;155 else156 ei->accum_energy += UINT_MAX - ei->reg_val_prev + reg_val;157 ei->reg_val_prev = reg_val;158 159 *energy = mul_u64_u32_shr(ei->accum_energy, SF_ENERGY,160 hwmon->scl_shift_energy);161 mutex_unlock(&hwmon->hwmon_lock);162 }163}164 165static ssize_t166hwm_power1_max_interval_show(struct device *dev, struct device_attribute *attr,167 char *buf)168{169 struct hwm_drvdata *ddat = dev_get_drvdata(dev);170 struct i915_hwmon *hwmon = ddat->hwmon;171 intel_wakeref_t wakeref;172 u32 r, x, y, x_w = 2; /* 2 bits */173 u64 tau4, out;174 175 with_intel_runtime_pm(ddat->uncore->rpm, wakeref)176 r = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_rapl_limit);177 178 x = REG_FIELD_GET(PKG_PWR_LIM_1_TIME_X, r);179 y = REG_FIELD_GET(PKG_PWR_LIM_1_TIME_Y, r);180 /*181 * tau = 1.x * power(2,y), x = bits(23:22), y = bits(21:17)182 * = (4 | x) << (y - 2)183 * where (y - 2) ensures a 1.x fixed point representation of 1.x184 * However because y can be < 2, we compute185 * tau4 = (4 | x) << y186 * but add 2 when doing the final right shift to account for units187 */188 tau4 = (u64)((1 << x_w) | x) << y;189 /* val in hwmon interface units (millisec) */190 out = mul_u64_u32_shr(tau4, SF_TIME, hwmon->scl_shift_time + x_w);191 192 return sysfs_emit(buf, "%llu\n", out);193}194 195static ssize_t196hwm_power1_max_interval_store(struct device *dev,197 struct device_attribute *attr,198 const char *buf, size_t count)199{200 struct hwm_drvdata *ddat = dev_get_drvdata(dev);201 struct i915_hwmon *hwmon = ddat->hwmon;202 u32 x, y, rxy, x_w = 2; /* 2 bits */203 u64 tau4, r, max_win;204 unsigned long val;205 int ret;206 207 ret = kstrtoul(buf, 0, &val);208 if (ret)209 return ret;210 211 /*212 * Max HW supported tau in '1.x * power(2,y)' format, x = 0, y = 0x12213 * The hwmon->scl_shift_time default of 0xa results in a max tau of 256 seconds214 */215#define PKG_MAX_WIN_DEFAULT 0x12ull216 217 /*218 * val must be < max in hwmon interface units. The steps below are219 * explained in i915_power1_max_interval_show()220 */221 r = FIELD_PREP(PKG_MAX_WIN, PKG_MAX_WIN_DEFAULT);222 x = REG_FIELD_GET(PKG_MAX_WIN_X, r);223 y = REG_FIELD_GET(PKG_MAX_WIN_Y, r);224 tau4 = (u64)((1 << x_w) | x) << y;225 max_win = mul_u64_u32_shr(tau4, SF_TIME, hwmon->scl_shift_time + x_w);226 227 if (val > max_win)228 return -EINVAL;229 230 /* val in hw units */231 val = DIV_ROUND_CLOSEST_ULL((u64)val << hwmon->scl_shift_time, SF_TIME);232 /* Convert to 1.x * power(2,y) */233 if (!val) {234 /* Avoid ilog2(0) */235 y = 0;236 x = 0;237 } else {238 y = ilog2(val);239 /* x = (val - (1 << y)) >> (y - 2); */240 x = (val - (1ul << y)) << x_w >> y;241 }242 243 rxy = REG_FIELD_PREP(PKG_PWR_LIM_1_TIME_X, x) | REG_FIELD_PREP(PKG_PWR_LIM_1_TIME_Y, y);244 245 hwm_locked_with_pm_intel_uncore_rmw(ddat, hwmon->rg.pkg_rapl_limit,246 PKG_PWR_LIM_1_TIME, rxy);247 return count;248}249 250static SENSOR_DEVICE_ATTR(power1_max_interval, 0664,251 hwm_power1_max_interval_show,252 hwm_power1_max_interval_store, 0);253 254static struct attribute *hwm_attributes[] = {255 &sensor_dev_attr_power1_max_interval.dev_attr.attr,256 NULL257};258 259static umode_t hwm_attributes_visible(struct kobject *kobj,260 struct attribute *attr, int index)261{262 struct device *dev = kobj_to_dev(kobj);263 struct hwm_drvdata *ddat = dev_get_drvdata(dev);264 struct i915_hwmon *hwmon = ddat->hwmon;265 266 if (attr == &sensor_dev_attr_power1_max_interval.dev_attr.attr)267 return i915_mmio_reg_valid(hwmon->rg.pkg_rapl_limit) ? attr->mode : 0;268 269 return 0;270}271 272static const struct attribute_group hwm_attrgroup = {273 .attrs = hwm_attributes,274 .is_visible = hwm_attributes_visible,275};276 277static const struct attribute_group *hwm_groups[] = {278 &hwm_attrgroup,279 NULL280};281 282static const struct hwmon_channel_info * const hwm_info[] = {283 HWMON_CHANNEL_INFO(in, HWMON_I_INPUT),284 HWMON_CHANNEL_INFO(power, HWMON_P_MAX | HWMON_P_RATED_MAX | HWMON_P_CRIT),285 HWMON_CHANNEL_INFO(energy, HWMON_E_INPUT),286 HWMON_CHANNEL_INFO(curr, HWMON_C_CRIT),287 HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT),288 NULL289};290 291static const struct hwmon_channel_info * const hwm_gt_info[] = {292 HWMON_CHANNEL_INFO(energy, HWMON_E_INPUT),293 NULL294};295 296/* I1 is exposed as power_crit or as curr_crit depending on bit 31 */297static int hwm_pcode_read_i1(struct drm_i915_private *i915, u32 *uval)298{299 /* Avoid ILLEGAL_SUBCOMMAND "mailbox access failed" warning in snb_pcode_read */300 if (IS_DG1(i915) || IS_DG2(i915))301 return -ENXIO;302 303 return snb_pcode_read_p(&i915->uncore, PCODE_POWER_SETUP,304 POWER_SETUP_SUBCOMMAND_READ_I1, 0, uval);305}306 307static int hwm_pcode_write_i1(struct drm_i915_private *i915, u32 uval)308{309 return snb_pcode_write_p(&i915->uncore, PCODE_POWER_SETUP,310 POWER_SETUP_SUBCOMMAND_WRITE_I1, 0, uval);311}312 313static umode_t314hwm_in_is_visible(const struct hwm_drvdata *ddat, u32 attr)315{316 struct drm_i915_private *i915 = ddat->uncore->i915;317 318 switch (attr) {319 case hwmon_in_input:320 return IS_DG1(i915) || IS_DG2(i915) ? 0444 : 0;321 default:322 return 0;323 }324}325 326static int327hwm_in_read(struct hwm_drvdata *ddat, u32 attr, long *val)328{329 struct i915_hwmon *hwmon = ddat->hwmon;330 intel_wakeref_t wakeref;331 u32 reg_value;332 333 switch (attr) {334 case hwmon_in_input:335 with_intel_runtime_pm(ddat->uncore->rpm, wakeref)336 reg_value = intel_uncore_read(ddat->uncore, hwmon->rg.gt_perf_status);337 /* HW register value in units of 2.5 millivolt */338 *val = DIV_ROUND_CLOSEST(REG_FIELD_GET(GEN12_VOLTAGE_MASK, reg_value) * 25, 10);339 return 0;340 default:341 return -EOPNOTSUPP;342 }343}344 345static umode_t346hwm_power_is_visible(const struct hwm_drvdata *ddat, u32 attr, int chan)347{348 struct drm_i915_private *i915 = ddat->uncore->i915;349 struct i915_hwmon *hwmon = ddat->hwmon;350 u32 uval;351 352 switch (attr) {353 case hwmon_power_max:354 return i915_mmio_reg_valid(hwmon->rg.pkg_rapl_limit) ? 0664 : 0;355 case hwmon_power_rated_max:356 return i915_mmio_reg_valid(hwmon->rg.pkg_power_sku) ? 0444 : 0;357 case hwmon_power_crit:358 return (hwm_pcode_read_i1(i915, &uval) ||359 !(uval & POWER_SETUP_I1_WATTS)) ? 0 : 0644;360 default:361 return 0;362 }363}364 365#define PL1_DISABLE 0366 367/*368 * HW allows arbitrary PL1 limits to be set but silently clamps these values to369 * "typical but not guaranteed" min/max values in rg.pkg_power_sku. Follow the370 * same pattern for sysfs, allow arbitrary PL1 limits to be set but display371 * clamped values when read. Write/read I1 also follows the same pattern.372 */373static int374hwm_power_max_read(struct hwm_drvdata *ddat, long *val)375{376 struct i915_hwmon *hwmon = ddat->hwmon;377 intel_wakeref_t wakeref;378 u64 r, min, max;379 380 /* Check if PL1 limit is disabled */381 with_intel_runtime_pm(ddat->uncore->rpm, wakeref)382 r = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_rapl_limit);383 if (!(r & PKG_PWR_LIM_1_EN)) {384 *val = PL1_DISABLE;385 return 0;386 }387 388 *val = hwm_field_read_and_scale(ddat,389 hwmon->rg.pkg_rapl_limit,390 PKG_PWR_LIM_1,391 hwmon->scl_shift_power,392 SF_POWER);393 394 with_intel_runtime_pm(ddat->uncore->rpm, wakeref)395 r = intel_uncore_read64(ddat->uncore, hwmon->rg.pkg_power_sku);396 min = REG_FIELD_GET(PKG_MIN_PWR, r);397 min = mul_u64_u32_shr(min, SF_POWER, hwmon->scl_shift_power);398 max = REG_FIELD_GET(PKG_MAX_PWR, r);399 max = mul_u64_u32_shr(max, SF_POWER, hwmon->scl_shift_power);400 401 if (min && max)402 *val = clamp_t(u64, *val, min, max);403 404 return 0;405}406 407static int408hwm_power_max_write(struct hwm_drvdata *ddat, long val)409{410 struct i915_hwmon *hwmon = ddat->hwmon;411 intel_wakeref_t wakeref;412 DEFINE_WAIT(wait);413 int ret = 0;414 u32 nval;415 416 /* Block waiting for GuC reset to complete when needed */417 for (;;) {418 wakeref = intel_runtime_pm_get(ddat->uncore->rpm);419 mutex_lock(&hwmon->hwmon_lock);420 421 prepare_to_wait(&ddat->waitq, &wait, TASK_INTERRUPTIBLE);422 423 if (!hwmon->ddat.reset_in_progress)424 break;425 426 if (signal_pending(current)) {427 ret = -EINTR;428 break;429 }430 431 mutex_unlock(&hwmon->hwmon_lock);432 intel_runtime_pm_put(ddat->uncore->rpm, wakeref);433 434 schedule();435 }436 finish_wait(&ddat->waitq, &wait);437 if (ret)438 goto exit;439 440 /* Disable PL1 limit and verify, because the limit cannot be disabled on all platforms */441 if (val == PL1_DISABLE) {442 intel_uncore_rmw(ddat->uncore, hwmon->rg.pkg_rapl_limit,443 PKG_PWR_LIM_1_EN, 0);444 nval = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_rapl_limit);445 446 if (nval & PKG_PWR_LIM_1_EN)447 ret = -ENODEV;448 goto exit;449 }450 451 /* Computation in 64-bits to avoid overflow. Round to nearest. */452 nval = DIV_ROUND_CLOSEST_ULL((u64)val << hwmon->scl_shift_power, SF_POWER);453 nval = PKG_PWR_LIM_1_EN | REG_FIELD_PREP(PKG_PWR_LIM_1, nval);454 455 intel_uncore_rmw(ddat->uncore, hwmon->rg.pkg_rapl_limit,456 PKG_PWR_LIM_1_EN | PKG_PWR_LIM_1, nval);457exit:458 mutex_unlock(&hwmon->hwmon_lock);459 intel_runtime_pm_put(ddat->uncore->rpm, wakeref);460 return ret;461}462 463static int464hwm_power_read(struct hwm_drvdata *ddat, u32 attr, int chan, long *val)465{466 struct i915_hwmon *hwmon = ddat->hwmon;467 int ret;468 u32 uval;469 470 switch (attr) {471 case hwmon_power_max:472 return hwm_power_max_read(ddat, val);473 case hwmon_power_rated_max:474 *val = hwm_field_read_and_scale(ddat,475 hwmon->rg.pkg_power_sku,476 PKG_PKG_TDP,477 hwmon->scl_shift_power,478 SF_POWER);479 return 0;480 case hwmon_power_crit:481 ret = hwm_pcode_read_i1(ddat->uncore->i915, &uval);482 if (ret)483 return ret;484 if (!(uval & POWER_SETUP_I1_WATTS))485 return -ENODEV;486 *val = mul_u64_u32_shr(REG_FIELD_GET(POWER_SETUP_I1_DATA_MASK, uval),487 SF_POWER, POWER_SETUP_I1_SHIFT);488 return 0;489 default:490 return -EOPNOTSUPP;491 }492}493 494static int495hwm_power_write(struct hwm_drvdata *ddat, u32 attr, int chan, long val)496{497 u32 uval;498 499 switch (attr) {500 case hwmon_power_max:501 return hwm_power_max_write(ddat, val);502 case hwmon_power_crit:503 uval = DIV_ROUND_CLOSEST_ULL(val << POWER_SETUP_I1_SHIFT, SF_POWER);504 return hwm_pcode_write_i1(ddat->uncore->i915, uval);505 default:506 return -EOPNOTSUPP;507 }508}509 510void i915_hwmon_power_max_disable(struct drm_i915_private *i915, bool *old)511{512 struct i915_hwmon *hwmon = i915->hwmon;513 u32 r;514 515 if (!hwmon || !i915_mmio_reg_valid(hwmon->rg.pkg_rapl_limit))516 return;517 518 mutex_lock(&hwmon->hwmon_lock);519 520 hwmon->ddat.reset_in_progress = true;521 r = intel_uncore_rmw(hwmon->ddat.uncore, hwmon->rg.pkg_rapl_limit,522 PKG_PWR_LIM_1_EN, 0);523 *old = !!(r & PKG_PWR_LIM_1_EN);524 525 mutex_unlock(&hwmon->hwmon_lock);526}527 528void i915_hwmon_power_max_restore(struct drm_i915_private *i915, bool old)529{530 struct i915_hwmon *hwmon = i915->hwmon;531 532 if (!hwmon || !i915_mmio_reg_valid(hwmon->rg.pkg_rapl_limit))533 return;534 535 mutex_lock(&hwmon->hwmon_lock);536 537 intel_uncore_rmw(hwmon->ddat.uncore, hwmon->rg.pkg_rapl_limit,538 PKG_PWR_LIM_1_EN, old ? PKG_PWR_LIM_1_EN : 0);539 hwmon->ddat.reset_in_progress = false;540 wake_up_all(&hwmon->ddat.waitq);541 542 mutex_unlock(&hwmon->hwmon_lock);543}544 545static umode_t546hwm_energy_is_visible(const struct hwm_drvdata *ddat, u32 attr)547{548 struct i915_hwmon *hwmon = ddat->hwmon;549 i915_reg_t rgaddr;550 551 switch (attr) {552 case hwmon_energy_input:553 if (ddat->gt_n >= 0)554 rgaddr = hwmon->rg.energy_status_tile;555 else556 rgaddr = hwmon->rg.energy_status_all;557 return i915_mmio_reg_valid(rgaddr) ? 0444 : 0;558 default:559 return 0;560 }561}562 563static int564hwm_energy_read(struct hwm_drvdata *ddat, u32 attr, long *val)565{566 switch (attr) {567 case hwmon_energy_input:568 hwm_energy(ddat, val);569 return 0;570 default:571 return -EOPNOTSUPP;572 }573}574 575static umode_t576hwm_curr_is_visible(const struct hwm_drvdata *ddat, u32 attr)577{578 struct drm_i915_private *i915 = ddat->uncore->i915;579 u32 uval;580 581 switch (attr) {582 case hwmon_curr_crit:583 return (hwm_pcode_read_i1(i915, &uval) ||584 (uval & POWER_SETUP_I1_WATTS)) ? 0 : 0644;585 default:586 return 0;587 }588}589 590static int591hwm_curr_read(struct hwm_drvdata *ddat, u32 attr, long *val)592{593 int ret;594 u32 uval;595 596 switch (attr) {597 case hwmon_curr_crit:598 ret = hwm_pcode_read_i1(ddat->uncore->i915, &uval);599 if (ret)600 return ret;601 if (uval & POWER_SETUP_I1_WATTS)602 return -ENODEV;603 *val = mul_u64_u32_shr(REG_FIELD_GET(POWER_SETUP_I1_DATA_MASK, uval),604 SF_CURR, POWER_SETUP_I1_SHIFT);605 return 0;606 default:607 return -EOPNOTSUPP;608 }609}610 611static int612hwm_curr_write(struct hwm_drvdata *ddat, u32 attr, long val)613{614 u32 uval;615 616 switch (attr) {617 case hwmon_curr_crit:618 uval = DIV_ROUND_CLOSEST_ULL(val << POWER_SETUP_I1_SHIFT, SF_CURR);619 return hwm_pcode_write_i1(ddat->uncore->i915, uval);620 default:621 return -EOPNOTSUPP;622 }623}624 625static umode_t626hwm_fan_is_visible(const struct hwm_drvdata *ddat, u32 attr)627{628 struct i915_hwmon *hwmon = ddat->hwmon;629 630 if (attr == hwmon_fan_input && i915_mmio_reg_valid(hwmon->rg.fan_speed))631 return 0444;632 633 return 0;634}635 636static int637hwm_fan_input_read(struct hwm_drvdata *ddat, long *val)638{639 struct i915_hwmon *hwmon = ddat->hwmon;640 struct hwm_fan_info *fi = &ddat->fi;641 u64 rotations, time_now, time;642 intel_wakeref_t wakeref;643 u32 reg_val;644 int ret = 0;645 646 wakeref = intel_runtime_pm_get(ddat->uncore->rpm);647 mutex_lock(&hwmon->hwmon_lock);648 649 reg_val = intel_uncore_read(ddat->uncore, hwmon->rg.fan_speed);650 time_now = get_jiffies_64();651 652 /*653 * HW register value is accumulated count of pulses from654 * PWM fan with the scale of 2 pulses per rotation.655 */656 rotations = (reg_val - fi->reg_val_prev) / 2;657 658 time = jiffies_delta_to_msecs(time_now - fi->time_prev);659 if (unlikely(!time)) {660 ret = -EAGAIN;661 goto exit;662 }663 664 /*665 * Calculate fan speed in RPM by time averaging two subsequent666 * readings in minutes.667 * RPM = number of rotations * msecs per minute / time in msecs668 */669 *val = DIV_ROUND_UP_ULL(rotations * (MSEC_PER_SEC * 60), time);670 671 fi->reg_val_prev = reg_val;672 fi->time_prev = time_now;673exit:674 mutex_unlock(&hwmon->hwmon_lock);675 intel_runtime_pm_put(ddat->uncore->rpm, wakeref);676 return ret;677}678 679static int680hwm_fan_read(struct hwm_drvdata *ddat, u32 attr, long *val)681{682 if (attr == hwmon_fan_input)683 return hwm_fan_input_read(ddat, val);684 685 return -EOPNOTSUPP;686}687 688static umode_t689hwm_is_visible(const void *drvdata, enum hwmon_sensor_types type,690 u32 attr, int channel)691{692 struct hwm_drvdata *ddat = (struct hwm_drvdata *)drvdata;693 694 switch (type) {695 case hwmon_in:696 return hwm_in_is_visible(ddat, attr);697 case hwmon_power:698 return hwm_power_is_visible(ddat, attr, channel);699 case hwmon_energy:700 return hwm_energy_is_visible(ddat, attr);701 case hwmon_curr:702 return hwm_curr_is_visible(ddat, attr);703 case hwmon_fan:704 return hwm_fan_is_visible(ddat, attr);705 default:706 return 0;707 }708}709 710static int711hwm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,712 int channel, long *val)713{714 struct hwm_drvdata *ddat = dev_get_drvdata(dev);715 716 switch (type) {717 case hwmon_in:718 return hwm_in_read(ddat, attr, val);719 case hwmon_power:720 return hwm_power_read(ddat, attr, channel, val);721 case hwmon_energy:722 return hwm_energy_read(ddat, attr, val);723 case hwmon_curr:724 return hwm_curr_read(ddat, attr, val);725 case hwmon_fan:726 return hwm_fan_read(ddat, attr, val);727 default:728 return -EOPNOTSUPP;729 }730}731 732static int733hwm_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,734 int channel, long val)735{736 struct hwm_drvdata *ddat = dev_get_drvdata(dev);737 738 switch (type) {739 case hwmon_power:740 return hwm_power_write(ddat, attr, channel, val);741 case hwmon_curr:742 return hwm_curr_write(ddat, attr, val);743 default:744 return -EOPNOTSUPP;745 }746}747 748static const struct hwmon_ops hwm_ops = {749 .is_visible = hwm_is_visible,750 .read = hwm_read,751 .write = hwm_write,752};753 754static const struct hwmon_chip_info hwm_chip_info = {755 .ops = &hwm_ops,756 .info = hwm_info,757};758 759static umode_t760hwm_gt_is_visible(const void *drvdata, enum hwmon_sensor_types type,761 u32 attr, int channel)762{763 struct hwm_drvdata *ddat = (struct hwm_drvdata *)drvdata;764 765 switch (type) {766 case hwmon_energy:767 return hwm_energy_is_visible(ddat, attr);768 default:769 return 0;770 }771}772 773static int774hwm_gt_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,775 int channel, long *val)776{777 struct hwm_drvdata *ddat = dev_get_drvdata(dev);778 779 switch (type) {780 case hwmon_energy:781 return hwm_energy_read(ddat, attr, val);782 default:783 return -EOPNOTSUPP;784 }785}786 787static const struct hwmon_ops hwm_gt_ops = {788 .is_visible = hwm_gt_is_visible,789 .read = hwm_gt_read,790};791 792static const struct hwmon_chip_info hwm_gt_chip_info = {793 .ops = &hwm_gt_ops,794 .info = hwm_gt_info,795};796 797static void798hwm_get_preregistration_info(struct drm_i915_private *i915)799{800 struct i915_hwmon *hwmon = i915->hwmon;801 struct intel_uncore *uncore = &i915->uncore;802 struct hwm_drvdata *ddat = &hwmon->ddat;803 intel_wakeref_t wakeref;804 u32 val_sku_unit = 0;805 struct intel_gt *gt;806 long energy;807 int i;808 809 /* Available for all Gen12+/dGfx */810 hwmon->rg.gt_perf_status = GEN12_RPSTAT1;811 812 if (IS_DG1(i915) || IS_DG2(i915)) {813 hwmon->rg.pkg_power_sku_unit = PCU_PACKAGE_POWER_SKU_UNIT;814 hwmon->rg.pkg_power_sku = PCU_PACKAGE_POWER_SKU;815 hwmon->rg.pkg_rapl_limit = PCU_PACKAGE_RAPL_LIMIT;816 hwmon->rg.energy_status_all = PCU_PACKAGE_ENERGY_STATUS;817 hwmon->rg.energy_status_tile = INVALID_MMIO_REG;818 hwmon->rg.fan_speed = PCU_PWM_FAN_SPEED;819 } else {820 hwmon->rg.pkg_power_sku_unit = INVALID_MMIO_REG;821 hwmon->rg.pkg_power_sku = INVALID_MMIO_REG;822 hwmon->rg.pkg_rapl_limit = INVALID_MMIO_REG;823 hwmon->rg.energy_status_all = INVALID_MMIO_REG;824 hwmon->rg.energy_status_tile = INVALID_MMIO_REG;825 hwmon->rg.fan_speed = INVALID_MMIO_REG;826 }827 828 with_intel_runtime_pm(uncore->rpm, wakeref) {829 /*830 * The contents of register hwmon->rg.pkg_power_sku_unit do not change,831 * so read it once and store the shift values.832 */833 if (i915_mmio_reg_valid(hwmon->rg.pkg_power_sku_unit))834 val_sku_unit = intel_uncore_read(uncore,835 hwmon->rg.pkg_power_sku_unit);836 837 /*838 * Store the initial fan register value, so that we can use it for839 * initial fan speed calculation.840 */841 if (i915_mmio_reg_valid(hwmon->rg.fan_speed)) {842 ddat->fi.reg_val_prev = intel_uncore_read(uncore,843 hwmon->rg.fan_speed);844 ddat->fi.time_prev = get_jiffies_64();845 }846 }847 848 hwmon->scl_shift_power = REG_FIELD_GET(PKG_PWR_UNIT, val_sku_unit);849 hwmon->scl_shift_energy = REG_FIELD_GET(PKG_ENERGY_UNIT, val_sku_unit);850 hwmon->scl_shift_time = REG_FIELD_GET(PKG_TIME_UNIT, val_sku_unit);851 852 /*853 * Initialize 'struct hwm_energy_info', i.e. set fields to the854 * first value of the energy register read855 */856 if (i915_mmio_reg_valid(hwmon->rg.energy_status_all))857 hwm_energy(ddat, &energy);858 if (i915_mmio_reg_valid(hwmon->rg.energy_status_tile)) {859 for_each_gt(gt, i915, i)860 hwm_energy(&hwmon->ddat_gt[i], &energy);861 }862}863 864void i915_hwmon_register(struct drm_i915_private *i915)865{866 struct device *dev = i915->drm.dev;867 struct i915_hwmon *hwmon;868 struct device *hwmon_dev;869 struct hwm_drvdata *ddat;870 struct hwm_drvdata *ddat_gt;871 struct intel_gt *gt;872 int i;873 874 /* hwmon is available only for dGfx */875 if (!IS_DGFX(i915))876 return;877 878 hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);879 if (!hwmon)880 return;881 882 i915->hwmon = hwmon;883 mutex_init(&hwmon->hwmon_lock);884 ddat = &hwmon->ddat;885 886 ddat->hwmon = hwmon;887 ddat->uncore = &i915->uncore;888 snprintf(ddat->name, sizeof(ddat->name), "i915");889 ddat->gt_n = -1;890 init_waitqueue_head(&ddat->waitq);891 892 for_each_gt(gt, i915, i) {893 ddat_gt = hwmon->ddat_gt + i;894 895 ddat_gt->hwmon = hwmon;896 ddat_gt->uncore = gt->uncore;897 snprintf(ddat_gt->name, sizeof(ddat_gt->name), "i915_gt%u", i);898 ddat_gt->gt_n = i;899 }900 901 hwm_get_preregistration_info(i915);902 903 /* hwmon_dev points to device hwmon<i> */904 hwmon_dev = hwmon_device_register_with_info(dev, ddat->name,905 ddat,906 &hwm_chip_info,907 hwm_groups);908 if (IS_ERR(hwmon_dev))909 goto err;910 911 ddat->hwmon_dev = hwmon_dev;912 913 for_each_gt(gt, i915, i) {914 ddat_gt = hwmon->ddat_gt + i;915 /*916 * Create per-gt directories only if a per-gt attribute is917 * visible. Currently this is only energy918 */919 if (!hwm_gt_is_visible(ddat_gt, hwmon_energy, hwmon_energy_input, 0))920 continue;921 922 hwmon_dev = hwmon_device_register_with_info(dev, ddat_gt->name,923 ddat_gt,924 &hwm_gt_chip_info,925 NULL);926 if (!IS_ERR(hwmon_dev))927 ddat_gt->hwmon_dev = hwmon_dev;928 }929 return;930err:931 i915_hwmon_unregister(i915);932}933 934void i915_hwmon_unregister(struct drm_i915_private *i915)935{936 struct i915_hwmon *hwmon = i915->hwmon;937 struct intel_gt *gt;938 int i;939 940 if (!hwmon)941 return;942 943 for_each_gt(gt, i915, i)944 if (hwmon->ddat_gt[i].hwmon_dev)945 hwmon_device_unregister(hwmon->ddat_gt[i].hwmon_dev);946 947 if (hwmon->ddat.hwmon_dev)948 hwmon_device_unregister(hwmon->ddat.hwmon_dev);949 950 mutex_destroy(&hwmon->hwmon_lock);951 952 kfree(i915->hwmon);953 i915->hwmon = NULL;954}955