1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 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 Throttle 18 * 19 * Provides sysfs entries and other helpers for frequency throttle reasons in GT 20 * 21 * device/gt#/freq0/throttle/status - Overall status 22 * device/gt#/freq0/throttle/reason_pl1 - Frequency throttle due to PL1 23 * device/gt#/freq0/throttle/reason_pl2 - Frequency throttle due to PL2 24 * device/gt#/freq0/throttle/reason_pl4 - Frequency throttle due to PL4, Iccmax etc. 25 * device/gt#/freq0/throttle/reason_thermal - Frequency throttle due to thermal 26 * device/gt#/freq0/throttle/reason_prochot - Frequency throttle due to prochot 27 * device/gt#/freq0/throttle/reason_ratl - Frequency throttle due to RATL 28 * device/gt#/freq0/throttle/reason_vr_thermalert - Frequency throttle due to VR THERMALERT 29 * device/gt#/freq0/throttle/reason_vr_tdc - Frequency throttle due to VR TDC 30 */ 31 32 static struct xe_gt * 33 dev_to_gt(struct device *dev) 34 { 35 return kobj_to_gt(dev->kobj.parent); 36 } 37 38 u32 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 else 46 reg = xe_mmio_read32(gt, GT0_PERF_LIMIT_REASONS); 47 xe_pm_runtime_put(gt_to_xe(gt)); 48 49 return reg; 50 } 51 52 static 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 59 static 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 66 static 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 73 static 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 80 static 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 87 static 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 94 static 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 101 static 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 108 static 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 115 static 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 } 124 static DEVICE_ATTR_RO(status); 125 126 static 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 } 135 static DEVICE_ATTR_RO(reason_pl1); 136 137 static 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 } 146 static DEVICE_ATTR_RO(reason_pl2); 147 148 static 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 } 157 static DEVICE_ATTR_RO(reason_pl4); 158 159 static 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 } 168 static DEVICE_ATTR_RO(reason_thermal); 169 170 static 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 } 179 static DEVICE_ATTR_RO(reason_prochot); 180 181 static 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 } 190 static DEVICE_ATTR_RO(reason_ratl); 191 192 static 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 } 201 static DEVICE_ATTR_RO(reason_vr_thermalert); 202 203 static 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 } 212 static DEVICE_ATTR_RO(reason_vr_tdc); 213 214 static 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 NULL 225 }; 226 227 static const struct attribute_group throttle_group_attrs = { 228 .name = "throttle", 229 .attrs = throttle_attrs, 230 }; 231 232 static 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 239 int 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