Lines Matching +full:attr +full:- +full:max +full:- +full:name

1 // SPDX-License-Identifier: MIT
7 #include <linux/hwmon-sysfs.h>
19 * SF_* - scale factors for particular quantities according to hwmon spec.
20 * - voltage - millivolts
21 * - power - microwatts
22 * - curr - milliamperes
23 * - energy - microjoules
24 * - time - milliseconds
51 char name[12]; member
71 struct i915_hwmon *hwmon = ddat->hwmon; in hwm_locked_with_pm_intel_uncore_rmw()
72 struct intel_uncore *uncore = ddat->uncore; in hwm_locked_with_pm_intel_uncore_rmw()
75 mutex_lock(&hwmon->hwmon_lock); in hwm_locked_with_pm_intel_uncore_rmw()
77 with_intel_runtime_pm(uncore->rpm, wakeref) in hwm_locked_with_pm_intel_uncore_rmw()
80 mutex_unlock(&hwmon->hwmon_lock); in hwm_locked_with_pm_intel_uncore_rmw()
85 * of the field taken from the 32-bit register value might cause a result to
92 struct intel_uncore *uncore = ddat->uncore; in hwm_field_read_and_scale()
96 with_intel_runtime_pm(uncore->rpm, wakeref) in hwm_field_read_and_scale()
105 * hwm_energy - Obtain energy value
107 * The underlying energy hardware register is 32-bits and is subject to
110 * a power draw of 1000 watts, the 32-bit counter will overflow in
114 * 1 watt: (2^32 >> 14) / 1 W / (60 * 60 * 24) secs/day -> 3 days
115 * 1000 watts: (2^32 >> 14) / 1000 W / 60 secs/min -> 4.36 minutes
121 * hwmon->scl_shift_energy of 14 bits we have 57 (63 - 20 + 14) bits before
127 struct intel_uncore *uncore = ddat->uncore; in hwm_energy()
128 struct i915_hwmon *hwmon = ddat->hwmon; in hwm_energy()
129 struct hwm_energy_info *ei = &ddat->ei; in hwm_energy()
134 if (ddat->gt_n >= 0) in hwm_energy()
135 rgaddr = hwmon->rg.energy_status_tile; in hwm_energy()
137 rgaddr = hwmon->rg.energy_status_all; in hwm_energy()
139 mutex_lock(&hwmon->hwmon_lock); in hwm_energy()
141 with_intel_runtime_pm(uncore->rpm, wakeref) in hwm_energy()
144 if (reg_val >= ei->reg_val_prev) in hwm_energy()
145 ei->accum_energy += reg_val - ei->reg_val_prev; in hwm_energy()
147 ei->accum_energy += UINT_MAX - ei->reg_val_prev + reg_val; in hwm_energy()
148 ei->reg_val_prev = reg_val; in hwm_energy()
150 *energy = mul_u64_u32_shr(ei->accum_energy, SF_ENERGY, in hwm_energy()
151 hwmon->scl_shift_energy); in hwm_energy()
152 mutex_unlock(&hwmon->hwmon_lock); in hwm_energy()
156 hwm_power1_max_interval_show(struct device *dev, struct device_attribute *attr, in hwm_power1_max_interval_show() argument
160 struct i915_hwmon *hwmon = ddat->hwmon; in hwm_power1_max_interval_show()
165 with_intel_runtime_pm(ddat->uncore->rpm, wakeref) in hwm_power1_max_interval_show()
166 r = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_rapl_limit); in hwm_power1_max_interval_show()
172 * = (4 | x) << (y - 2) in hwm_power1_max_interval_show()
173 * where (y - 2) ensures a 1.x fixed point representation of 1.x in hwm_power1_max_interval_show()
180 out = mul_u64_u32_shr(tau4, SF_TIME, hwmon->scl_shift_time + x_w); in hwm_power1_max_interval_show()
187 struct device_attribute *attr, in hwm_power1_max_interval_store() argument
191 struct i915_hwmon *hwmon = ddat->hwmon; in hwm_power1_max_interval_store()
202 * Max HW supported tau in '1.x * power(2,y)' format, x = 0, y = 0x12 in hwm_power1_max_interval_store()
203 * The hwmon->scl_shift_time default of 0xa results in a max tau of 256 seconds in hwm_power1_max_interval_store()
208 * val must be < max in hwmon interface units. The steps below are in hwm_power1_max_interval_store()
215 max_win = mul_u64_u32_shr(tau4, SF_TIME, hwmon->scl_shift_time + x_w); in hwm_power1_max_interval_store()
218 return -EINVAL; in hwm_power1_max_interval_store()
221 val = DIV_ROUND_CLOSEST_ULL((u64)val << hwmon->scl_shift_time, SF_TIME); in hwm_power1_max_interval_store()
229 /* x = (val - (1 << y)) >> (y - 2); */ in hwm_power1_max_interval_store()
230 x = (val - (1ul << y)) << x_w >> y; in hwm_power1_max_interval_store()
235 hwm_locked_with_pm_intel_uncore_rmw(ddat, hwmon->rg.pkg_rapl_limit, in hwm_power1_max_interval_store()
245 &sensor_dev_attr_power1_max_interval.dev_attr.attr,
250 struct attribute *attr, int index) in hwm_attributes_visible() argument
254 struct i915_hwmon *hwmon = ddat->hwmon; in hwm_attributes_visible()
256 if (attr == &sensor_dev_attr_power1_max_interval.dev_attr.attr) in hwm_attributes_visible()
257 return i915_mmio_reg_valid(hwmon->rg.pkg_rapl_limit) ? attr->mode : 0; in hwm_attributes_visible()
290 return -ENXIO; in hwm_pcode_read_i1()
292 return snb_pcode_read_p(&i915->uncore, PCODE_POWER_SETUP, in hwm_pcode_read_i1()
298 return snb_pcode_write_p(&i915->uncore, PCODE_POWER_SETUP, in hwm_pcode_write_i1()
303 hwm_in_is_visible(const struct hwm_drvdata *ddat, u32 attr) in hwm_in_is_visible() argument
305 struct drm_i915_private *i915 = ddat->uncore->i915; in hwm_in_is_visible()
307 switch (attr) { in hwm_in_is_visible()
316 hwm_in_read(struct hwm_drvdata *ddat, u32 attr, long *val) in hwm_in_read() argument
318 struct i915_hwmon *hwmon = ddat->hwmon; in hwm_in_read()
322 switch (attr) { in hwm_in_read()
324 with_intel_runtime_pm(ddat->uncore->rpm, wakeref) in hwm_in_read()
325 reg_value = intel_uncore_read(ddat->uncore, hwmon->rg.gt_perf_status); in hwm_in_read()
330 return -EOPNOTSUPP; in hwm_in_read()
335 hwm_power_is_visible(const struct hwm_drvdata *ddat, u32 attr, int chan) in hwm_power_is_visible() argument
337 struct drm_i915_private *i915 = ddat->uncore->i915; in hwm_power_is_visible()
338 struct i915_hwmon *hwmon = ddat->hwmon; in hwm_power_is_visible()
341 switch (attr) { in hwm_power_is_visible()
343 return i915_mmio_reg_valid(hwmon->rg.pkg_rapl_limit) ? 0664 : 0; in hwm_power_is_visible()
345 return i915_mmio_reg_valid(hwmon->rg.pkg_power_sku) ? 0444 : 0; in hwm_power_is_visible()
358 * "typical but not guaranteed" min/max values in rg.pkg_power_sku. Follow the
365 struct i915_hwmon *hwmon = ddat->hwmon; in hwm_power_max_read()
367 u64 r, min, max; in hwm_power_max_read() local
370 with_intel_runtime_pm(ddat->uncore->rpm, wakeref) in hwm_power_max_read()
371 r = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_rapl_limit); in hwm_power_max_read()
378 hwmon->rg.pkg_rapl_limit, in hwm_power_max_read()
380 hwmon->scl_shift_power, in hwm_power_max_read()
383 with_intel_runtime_pm(ddat->uncore->rpm, wakeref) in hwm_power_max_read()
384 r = intel_uncore_read64(ddat->uncore, hwmon->rg.pkg_power_sku); in hwm_power_max_read()
386 min = mul_u64_u32_shr(min, SF_POWER, hwmon->scl_shift_power); in hwm_power_max_read()
387 max = REG_FIELD_GET(PKG_MAX_PWR, r); in hwm_power_max_read()
388 max = mul_u64_u32_shr(max, SF_POWER, hwmon->scl_shift_power); in hwm_power_max_read()
390 if (min && max) in hwm_power_max_read()
391 *val = clamp_t(u64, *val, min, max); in hwm_power_max_read()
399 struct i915_hwmon *hwmon = ddat->hwmon; in hwm_power_max_write()
407 mutex_lock(&hwmon->hwmon_lock); in hwm_power_max_write()
409 prepare_to_wait(&ddat->waitq, &wait, TASK_INTERRUPTIBLE); in hwm_power_max_write()
411 if (!hwmon->ddat.reset_in_progress) in hwm_power_max_write()
415 ret = -EINTR; in hwm_power_max_write()
419 mutex_unlock(&hwmon->hwmon_lock); in hwm_power_max_write()
423 finish_wait(&ddat->waitq, &wait); in hwm_power_max_write()
427 wakeref = intel_runtime_pm_get(ddat->uncore->rpm); in hwm_power_max_write()
431 intel_uncore_rmw(ddat->uncore, hwmon->rg.pkg_rapl_limit, in hwm_power_max_write()
433 nval = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_rapl_limit); in hwm_power_max_write()
436 ret = -ENODEV; in hwm_power_max_write()
440 /* Computation in 64-bits to avoid overflow. Round to nearest. */ in hwm_power_max_write()
441 nval = DIV_ROUND_CLOSEST_ULL((u64)val << hwmon->scl_shift_power, SF_POWER); in hwm_power_max_write()
444 intel_uncore_rmw(ddat->uncore, hwmon->rg.pkg_rapl_limit, in hwm_power_max_write()
447 intel_runtime_pm_put(ddat->uncore->rpm, wakeref); in hwm_power_max_write()
449 mutex_unlock(&hwmon->hwmon_lock); in hwm_power_max_write()
454 hwm_power_read(struct hwm_drvdata *ddat, u32 attr, int chan, long *val) in hwm_power_read() argument
456 struct i915_hwmon *hwmon = ddat->hwmon; in hwm_power_read()
460 switch (attr) { in hwm_power_read()
465 hwmon->rg.pkg_power_sku, in hwm_power_read()
467 hwmon->scl_shift_power, in hwm_power_read()
471 ret = hwm_pcode_read_i1(ddat->uncore->i915, &uval); in hwm_power_read()
475 return -ENODEV; in hwm_power_read()
480 return -EOPNOTSUPP; in hwm_power_read()
485 hwm_power_write(struct hwm_drvdata *ddat, u32 attr, int chan, long val) in hwm_power_write() argument
489 switch (attr) { in hwm_power_write()
494 return hwm_pcode_write_i1(ddat->uncore->i915, uval); in hwm_power_write()
496 return -EOPNOTSUPP; in hwm_power_write()
502 struct i915_hwmon *hwmon = i915->hwmon; in i915_hwmon_power_max_disable()
505 if (!hwmon || !i915_mmio_reg_valid(hwmon->rg.pkg_rapl_limit)) in i915_hwmon_power_max_disable()
508 mutex_lock(&hwmon->hwmon_lock); in i915_hwmon_power_max_disable()
510 hwmon->ddat.reset_in_progress = true; in i915_hwmon_power_max_disable()
511 r = intel_uncore_rmw(hwmon->ddat.uncore, hwmon->rg.pkg_rapl_limit, in i915_hwmon_power_max_disable()
515 mutex_unlock(&hwmon->hwmon_lock); in i915_hwmon_power_max_disable()
520 struct i915_hwmon *hwmon = i915->hwmon; in i915_hwmon_power_max_restore()
522 if (!hwmon || !i915_mmio_reg_valid(hwmon->rg.pkg_rapl_limit)) in i915_hwmon_power_max_restore()
525 mutex_lock(&hwmon->hwmon_lock); in i915_hwmon_power_max_restore()
527 intel_uncore_rmw(hwmon->ddat.uncore, hwmon->rg.pkg_rapl_limit, in i915_hwmon_power_max_restore()
529 hwmon->ddat.reset_in_progress = false; in i915_hwmon_power_max_restore()
530 wake_up_all(&hwmon->ddat.waitq); in i915_hwmon_power_max_restore()
532 mutex_unlock(&hwmon->hwmon_lock); in i915_hwmon_power_max_restore()
536 hwm_energy_is_visible(const struct hwm_drvdata *ddat, u32 attr) in hwm_energy_is_visible() argument
538 struct i915_hwmon *hwmon = ddat->hwmon; in hwm_energy_is_visible()
541 switch (attr) { in hwm_energy_is_visible()
543 if (ddat->gt_n >= 0) in hwm_energy_is_visible()
544 rgaddr = hwmon->rg.energy_status_tile; in hwm_energy_is_visible()
546 rgaddr = hwmon->rg.energy_status_all; in hwm_energy_is_visible()
554 hwm_energy_read(struct hwm_drvdata *ddat, u32 attr, long *val) in hwm_energy_read() argument
556 switch (attr) { in hwm_energy_read()
561 return -EOPNOTSUPP; in hwm_energy_read()
566 hwm_curr_is_visible(const struct hwm_drvdata *ddat, u32 attr) in hwm_curr_is_visible() argument
568 struct drm_i915_private *i915 = ddat->uncore->i915; in hwm_curr_is_visible()
571 switch (attr) { in hwm_curr_is_visible()
581 hwm_curr_read(struct hwm_drvdata *ddat, u32 attr, long *val) in hwm_curr_read() argument
586 switch (attr) { in hwm_curr_read()
588 ret = hwm_pcode_read_i1(ddat->uncore->i915, &uval); in hwm_curr_read()
592 return -ENODEV; in hwm_curr_read()
597 return -EOPNOTSUPP; in hwm_curr_read()
602 hwm_curr_write(struct hwm_drvdata *ddat, u32 attr, long val) in hwm_curr_write() argument
606 switch (attr) { in hwm_curr_write()
609 return hwm_pcode_write_i1(ddat->uncore->i915, uval); in hwm_curr_write()
611 return -EOPNOTSUPP; in hwm_curr_write()
617 u32 attr, int channel) in hwm_is_visible() argument
623 return hwm_in_is_visible(ddat, attr); in hwm_is_visible()
625 return hwm_power_is_visible(ddat, attr, channel); in hwm_is_visible()
627 return hwm_energy_is_visible(ddat, attr); in hwm_is_visible()
629 return hwm_curr_is_visible(ddat, attr); in hwm_is_visible()
636 hwm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, in hwm_read() argument
643 return hwm_in_read(ddat, attr, val); in hwm_read()
645 return hwm_power_read(ddat, attr, channel, val); in hwm_read()
647 return hwm_energy_read(ddat, attr, val); in hwm_read()
649 return hwm_curr_read(ddat, attr, val); in hwm_read()
651 return -EOPNOTSUPP; in hwm_read()
656 hwm_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, in hwm_write() argument
663 return hwm_power_write(ddat, attr, channel, val); in hwm_write()
665 return hwm_curr_write(ddat, attr, val); in hwm_write()
667 return -EOPNOTSUPP; in hwm_write()
684 u32 attr, int channel) in hwm_gt_is_visible() argument
690 return hwm_energy_is_visible(ddat, attr); in hwm_gt_is_visible()
697 hwm_gt_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, in hwm_gt_read() argument
704 return hwm_energy_read(ddat, attr, val); in hwm_gt_read()
706 return -EOPNOTSUPP; in hwm_gt_read()
723 struct i915_hwmon *hwmon = i915->hwmon; in hwm_get_preregistration_info()
724 struct intel_uncore *uncore = &i915->uncore; in hwm_get_preregistration_info()
725 struct hwm_drvdata *ddat = &hwmon->ddat; in hwm_get_preregistration_info()
733 hwmon->rg.gt_perf_status = GEN12_RPSTAT1; in hwm_get_preregistration_info()
736 hwmon->rg.pkg_power_sku_unit = PCU_PACKAGE_POWER_SKU_UNIT; in hwm_get_preregistration_info()
737 hwmon->rg.pkg_power_sku = PCU_PACKAGE_POWER_SKU; in hwm_get_preregistration_info()
738 hwmon->rg.pkg_rapl_limit = PCU_PACKAGE_RAPL_LIMIT; in hwm_get_preregistration_info()
739 hwmon->rg.energy_status_all = PCU_PACKAGE_ENERGY_STATUS; in hwm_get_preregistration_info()
740 hwmon->rg.energy_status_tile = INVALID_MMIO_REG; in hwm_get_preregistration_info()
742 hwmon->rg.pkg_power_sku_unit = GT0_PACKAGE_POWER_SKU_UNIT; in hwm_get_preregistration_info()
743 hwmon->rg.pkg_power_sku = INVALID_MMIO_REG; in hwm_get_preregistration_info()
744 hwmon->rg.pkg_rapl_limit = GT0_PACKAGE_RAPL_LIMIT; in hwm_get_preregistration_info()
745 hwmon->rg.energy_status_all = GT0_PLATFORM_ENERGY_STATUS; in hwm_get_preregistration_info()
746 hwmon->rg.energy_status_tile = GT0_PACKAGE_ENERGY_STATUS; in hwm_get_preregistration_info()
748 hwmon->rg.pkg_power_sku_unit = INVALID_MMIO_REG; in hwm_get_preregistration_info()
749 hwmon->rg.pkg_power_sku = INVALID_MMIO_REG; in hwm_get_preregistration_info()
750 hwmon->rg.pkg_rapl_limit = INVALID_MMIO_REG; in hwm_get_preregistration_info()
751 hwmon->rg.energy_status_all = INVALID_MMIO_REG; in hwm_get_preregistration_info()
752 hwmon->rg.energy_status_tile = INVALID_MMIO_REG; in hwm_get_preregistration_info()
755 with_intel_runtime_pm(uncore->rpm, wakeref) { in hwm_get_preregistration_info()
757 * The contents of register hwmon->rg.pkg_power_sku_unit do not change, in hwm_get_preregistration_info()
760 if (i915_mmio_reg_valid(hwmon->rg.pkg_power_sku_unit)) in hwm_get_preregistration_info()
762 hwmon->rg.pkg_power_sku_unit); in hwm_get_preregistration_info()
765 hwmon->scl_shift_power = REG_FIELD_GET(PKG_PWR_UNIT, val_sku_unit); in hwm_get_preregistration_info()
766 hwmon->scl_shift_energy = REG_FIELD_GET(PKG_ENERGY_UNIT, val_sku_unit); in hwm_get_preregistration_info()
767 hwmon->scl_shift_time = REG_FIELD_GET(PKG_TIME_UNIT, val_sku_unit); in hwm_get_preregistration_info()
773 if (i915_mmio_reg_valid(hwmon->rg.energy_status_all)) in hwm_get_preregistration_info()
775 if (i915_mmio_reg_valid(hwmon->rg.energy_status_tile)) { in hwm_get_preregistration_info()
777 hwm_energy(&hwmon->ddat_gt[i], &energy); in hwm_get_preregistration_info()
783 struct device *dev = i915->drm.dev; in i915_hwmon_register()
799 i915->hwmon = hwmon; in i915_hwmon_register()
800 mutex_init(&hwmon->hwmon_lock); in i915_hwmon_register()
801 ddat = &hwmon->ddat; in i915_hwmon_register()
803 ddat->hwmon = hwmon; in i915_hwmon_register()
804 ddat->uncore = &i915->uncore; in i915_hwmon_register()
805 snprintf(ddat->name, sizeof(ddat->name), "i915"); in i915_hwmon_register()
806 ddat->gt_n = -1; in i915_hwmon_register()
807 init_waitqueue_head(&ddat->waitq); in i915_hwmon_register()
810 ddat_gt = hwmon->ddat_gt + i; in i915_hwmon_register()
812 ddat_gt->hwmon = hwmon; in i915_hwmon_register()
813 ddat_gt->uncore = gt->uncore; in i915_hwmon_register()
814 snprintf(ddat_gt->name, sizeof(ddat_gt->name), "i915_gt%u", i); in i915_hwmon_register()
815 ddat_gt->gt_n = i; in i915_hwmon_register()
821 hwmon_dev = devm_hwmon_device_register_with_info(dev, ddat->name, in i915_hwmon_register()
826 i915->hwmon = NULL; in i915_hwmon_register()
830 ddat->hwmon_dev = hwmon_dev; in i915_hwmon_register()
833 ddat_gt = hwmon->ddat_gt + i; in i915_hwmon_register()
835 * Create per-gt directories only if a per-gt attribute is in i915_hwmon_register()
841 hwmon_dev = devm_hwmon_device_register_with_info(dev, ddat_gt->name, in i915_hwmon_register()
846 ddat_gt->hwmon_dev = hwmon_dev; in i915_hwmon_register()
852 fetch_and_zero(&i915->hwmon); in i915_hwmon_unregister()