brintos

brintos / linux-shallow public Read only

0
0
Text · 5.8 KiB · 25963e3 Raw
250 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2023 Intel Corporation4 */5 6#include <drm/drm_managed.h>7 8#include <regs/xe_gt_regs.h>9#include "xe_device.h"10#include "xe_gt.h"11#include "xe_gt_sysfs.h"12#include "xe_gt_throttle.h"13#include "xe_mmio.h"14#include "xe_pm.h"15 16/**17 * DOC: Xe GT Throttle18 *19 * Provides sysfs entries and other helpers for frequency throttle reasons in GT20 *21 * device/gt#/freq0/throttle/status - Overall status22 * device/gt#/freq0/throttle/reason_pl1 - Frequency throttle due to PL123 * device/gt#/freq0/throttle/reason_pl2 - Frequency throttle due to PL224 * device/gt#/freq0/throttle/reason_pl4 - Frequency throttle due to PL4, Iccmax etc.25 * device/gt#/freq0/throttle/reason_thermal - Frequency throttle due to thermal26 * device/gt#/freq0/throttle/reason_prochot - Frequency throttle due to prochot27 * device/gt#/freq0/throttle/reason_ratl - Frequency throttle due to RATL28 * device/gt#/freq0/throttle/reason_vr_thermalert - Frequency throttle due to VR THERMALERT29 * device/gt#/freq0/throttle/reason_vr_tdc -  Frequency throttle due to VR TDC30 */31 32static struct xe_gt *33dev_to_gt(struct device *dev)34{35	return kobj_to_gt(dev->kobj.parent);36}37 38u32 xe_gt_throttle_get_limit_reasons(struct xe_gt *gt)39{40	u32 reg;41 42	xe_pm_runtime_get(gt_to_xe(gt));43	if (xe_gt_is_media_type(gt))44		reg = xe_mmio_read32(gt, MTL_MEDIA_PERF_LIMIT_REASONS);45	else46		reg = xe_mmio_read32(gt, GT0_PERF_LIMIT_REASONS);47	xe_pm_runtime_put(gt_to_xe(gt));48 49	return reg;50}51 52static u32 read_status(struct xe_gt *gt)53{54	u32 status = xe_gt_throttle_get_limit_reasons(gt) & GT0_PERF_LIMIT_REASONS_MASK;55 56	return status;57}58 59static u32 read_reason_pl1(struct xe_gt *gt)60{61	u32 pl1 = xe_gt_throttle_get_limit_reasons(gt) & POWER_LIMIT_1_MASK;62 63	return pl1;64}65 66static u32 read_reason_pl2(struct xe_gt *gt)67{68	u32 pl2 = xe_gt_throttle_get_limit_reasons(gt) & POWER_LIMIT_2_MASK;69 70	return pl2;71}72 73static u32 read_reason_pl4(struct xe_gt *gt)74{75	u32 pl4 = xe_gt_throttle_get_limit_reasons(gt) & POWER_LIMIT_4_MASK;76 77	return pl4;78}79 80static u32 read_reason_thermal(struct xe_gt *gt)81{82	u32 thermal = xe_gt_throttle_get_limit_reasons(gt) & THERMAL_LIMIT_MASK;83 84	return thermal;85}86 87static u32 read_reason_prochot(struct xe_gt *gt)88{89	u32 prochot = xe_gt_throttle_get_limit_reasons(gt) & PROCHOT_MASK;90 91	return prochot;92}93 94static u32 read_reason_ratl(struct xe_gt *gt)95{96	u32 ratl = xe_gt_throttle_get_limit_reasons(gt) & RATL_MASK;97 98	return ratl;99}100 101static u32 read_reason_vr_thermalert(struct xe_gt *gt)102{103	u32 thermalert = xe_gt_throttle_get_limit_reasons(gt) & VR_THERMALERT_MASK;104 105	return thermalert;106}107 108static u32 read_reason_vr_tdc(struct xe_gt *gt)109{110	u32 tdc = xe_gt_throttle_get_limit_reasons(gt) & VR_TDC_MASK;111 112	return tdc;113}114 115static ssize_t status_show(struct device *dev,116			   struct device_attribute *attr,117			   char *buff)118{119	struct xe_gt *gt = dev_to_gt(dev);120	bool status = !!read_status(gt);121 122	return sysfs_emit(buff, "%u\n", status);123}124static DEVICE_ATTR_RO(status);125 126static ssize_t reason_pl1_show(struct device *dev,127			       struct device_attribute *attr,128			       char *buff)129{130	struct xe_gt *gt = dev_to_gt(dev);131	bool pl1 = !!read_reason_pl1(gt);132 133	return sysfs_emit(buff, "%u\n", pl1);134}135static DEVICE_ATTR_RO(reason_pl1);136 137static ssize_t reason_pl2_show(struct device *dev,138			       struct device_attribute *attr,139			       char *buff)140{141	struct xe_gt *gt = dev_to_gt(dev);142	bool pl2 = !!read_reason_pl2(gt);143 144	return sysfs_emit(buff, "%u\n", pl2);145}146static DEVICE_ATTR_RO(reason_pl2);147 148static ssize_t reason_pl4_show(struct device *dev,149			       struct device_attribute *attr,150			       char *buff)151{152	struct xe_gt *gt = dev_to_gt(dev);153	bool pl4 = !!read_reason_pl4(gt);154 155	return sysfs_emit(buff, "%u\n", pl4);156}157static DEVICE_ATTR_RO(reason_pl4);158 159static ssize_t reason_thermal_show(struct device *dev,160				   struct device_attribute *attr,161				   char *buff)162{163	struct xe_gt *gt = dev_to_gt(dev);164	bool thermal = !!read_reason_thermal(gt);165 166	return sysfs_emit(buff, "%u\n", thermal);167}168static DEVICE_ATTR_RO(reason_thermal);169 170static ssize_t reason_prochot_show(struct device *dev,171				   struct device_attribute *attr,172				   char *buff)173{174	struct xe_gt *gt = dev_to_gt(dev);175	bool prochot = !!read_reason_prochot(gt);176 177	return sysfs_emit(buff, "%u\n", prochot);178}179static DEVICE_ATTR_RO(reason_prochot);180 181static ssize_t reason_ratl_show(struct device *dev,182				struct device_attribute *attr,183				char *buff)184{185	struct xe_gt *gt = dev_to_gt(dev);186	bool ratl = !!read_reason_ratl(gt);187 188	return sysfs_emit(buff, "%u\n", ratl);189}190static DEVICE_ATTR_RO(reason_ratl);191 192static ssize_t reason_vr_thermalert_show(struct device *dev,193					 struct device_attribute *attr,194					 char *buff)195{196	struct xe_gt *gt = dev_to_gt(dev);197	bool thermalert = !!read_reason_vr_thermalert(gt);198 199	return sysfs_emit(buff, "%u\n", thermalert);200}201static DEVICE_ATTR_RO(reason_vr_thermalert);202 203static ssize_t reason_vr_tdc_show(struct device *dev,204				  struct device_attribute *attr,205				  char *buff)206{207	struct xe_gt *gt = dev_to_gt(dev);208	bool tdc = !!read_reason_vr_tdc(gt);209 210	return sysfs_emit(buff, "%u\n", tdc);211}212static DEVICE_ATTR_RO(reason_vr_tdc);213 214static struct attribute *throttle_attrs[] = {215	&dev_attr_status.attr,216	&dev_attr_reason_pl1.attr,217	&dev_attr_reason_pl2.attr,218	&dev_attr_reason_pl4.attr,219	&dev_attr_reason_thermal.attr,220	&dev_attr_reason_prochot.attr,221	&dev_attr_reason_ratl.attr,222	&dev_attr_reason_vr_thermalert.attr,223	&dev_attr_reason_vr_tdc.attr,224	NULL225};226 227static const struct attribute_group throttle_group_attrs = {228	.name = "throttle",229	.attrs = throttle_attrs,230};231 232static void gt_throttle_sysfs_fini(void *arg)233{234	struct xe_gt *gt = arg;235 236	sysfs_remove_group(gt->freq, &throttle_group_attrs);237}238 239int xe_gt_throttle_init(struct xe_gt *gt)240{241	struct xe_device *xe = gt_to_xe(gt);242	int err;243 244	err = sysfs_create_group(gt->freq, &throttle_group_attrs);245	if (err)246		return err;247 248	return devm_add_action_or_reset(xe->drm.dev, gt_throttle_sysfs_fini, gt);249}250