1 // SPDX-License-Identifier: GPL-2.0 2 3 /* 4 * Copyright 2016-2022 HabanaLabs, Ltd. 5 * All Rights Reserved. 6 */ 7 8 #include "goyaP.h" 9 10 void goya_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq) 11 { 12 struct goya_device *goya = hdev->asic_specific; 13 14 if (!hdev->pdev) 15 return; 16 17 switch (freq) { 18 case PLL_HIGH: 19 hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, hdev->high_pll); 20 hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, hdev->high_pll); 21 hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, hdev->high_pll); 22 break; 23 case PLL_LOW: 24 hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, GOYA_PLL_FREQ_LOW); 25 hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, GOYA_PLL_FREQ_LOW); 26 hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, GOYA_PLL_FREQ_LOW); 27 break; 28 case PLL_LAST: 29 hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, goya->mme_clk); 30 hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, goya->tpc_clk); 31 hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, goya->ic_clk); 32 break; 33 default: 34 dev_err(hdev->dev, "unknown frequency setting\n"); 35 } 36 } 37 38 static ssize_t mme_clk_show(struct device *dev, struct device_attribute *attr, 39 char *buf) 40 { 41 struct hl_device *hdev = dev_get_drvdata(dev); 42 long value; 43 44 if (!hl_device_operational(hdev, NULL)) 45 return -ENODEV; 46 47 value = hl_fw_get_frequency(hdev, HL_GOYA_MME_PLL, false); 48 49 if (value < 0) 50 return value; 51 52 return sprintf(buf, "%lu\n", value); 53 } 54 55 static ssize_t mme_clk_store(struct device *dev, struct device_attribute *attr, 56 const char *buf, size_t count) 57 { 58 struct hl_device *hdev = dev_get_drvdata(dev); 59 struct goya_device *goya = hdev->asic_specific; 60 int rc; 61 long value; 62 63 if (!hl_device_operational(hdev, NULL)) { 64 count = -ENODEV; 65 goto fail; 66 } 67 68 if (goya->pm_mng_profile == PM_AUTO) { 69 count = -EPERM; 70 goto fail; 71 } 72 73 rc = kstrtoul(buf, 0, &value); 74 75 if (rc) { 76 count = -EINVAL; 77 goto fail; 78 } 79 80 hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, value); 81 goya->mme_clk = value; 82 83 fail: 84 return count; 85 } 86 87 static ssize_t tpc_clk_show(struct device *dev, struct device_attribute *attr, 88 char *buf) 89 { 90 struct hl_device *hdev = dev_get_drvdata(dev); 91 long value; 92 93 if (!hl_device_operational(hdev, NULL)) 94 return -ENODEV; 95 96 value = hl_fw_get_frequency(hdev, HL_GOYA_TPC_PLL, false); 97 98 if (value < 0) 99 return value; 100 101 return sprintf(buf, "%lu\n", value); 102 } 103 104 static ssize_t tpc_clk_store(struct device *dev, struct device_attribute *attr, 105 const char *buf, size_t count) 106 { 107 struct hl_device *hdev = dev_get_drvdata(dev); 108 struct goya_device *goya = hdev->asic_specific; 109 int rc; 110 long value; 111 112 if (!hl_device_operational(hdev, NULL)) { 113 count = -ENODEV; 114 goto fail; 115 } 116 117 if (goya->pm_mng_profile == PM_AUTO) { 118 count = -EPERM; 119 goto fail; 120 } 121 122 rc = kstrtoul(buf, 0, &value); 123 124 if (rc) { 125 count = -EINVAL; 126 goto fail; 127 } 128 129 hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, value); 130 goya->tpc_clk = value; 131 132 fail: 133 return count; 134 } 135 136 static ssize_t ic_clk_show(struct device *dev, struct device_attribute *attr, 137 char *buf) 138 { 139 struct hl_device *hdev = dev_get_drvdata(dev); 140 long value; 141 142 if (!hl_device_operational(hdev, NULL)) 143 return -ENODEV; 144 145 value = hl_fw_get_frequency(hdev, HL_GOYA_IC_PLL, false); 146 147 if (value < 0) 148 return value; 149 150 return sprintf(buf, "%lu\n", value); 151 } 152 153 static ssize_t ic_clk_store(struct device *dev, struct device_attribute *attr, 154 const char *buf, size_t count) 155 { 156 struct hl_device *hdev = dev_get_drvdata(dev); 157 struct goya_device *goya = hdev->asic_specific; 158 int rc; 159 long value; 160 161 if (!hl_device_operational(hdev, NULL)) { 162 count = -ENODEV; 163 goto fail; 164 } 165 166 if (goya->pm_mng_profile == PM_AUTO) { 167 count = -EPERM; 168 goto fail; 169 } 170 171 rc = kstrtoul(buf, 0, &value); 172 173 if (rc) { 174 count = -EINVAL; 175 goto fail; 176 } 177 178 hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, value); 179 goya->ic_clk = value; 180 181 fail: 182 return count; 183 } 184 185 static ssize_t mme_clk_curr_show(struct device *dev, 186 struct device_attribute *attr, char *buf) 187 { 188 struct hl_device *hdev = dev_get_drvdata(dev); 189 long value; 190 191 if (!hl_device_operational(hdev, NULL)) 192 return -ENODEV; 193 194 value = hl_fw_get_frequency(hdev, HL_GOYA_MME_PLL, true); 195 196 if (value < 0) 197 return value; 198 199 return sprintf(buf, "%lu\n", value); 200 } 201 202 static ssize_t tpc_clk_curr_show(struct device *dev, 203 struct device_attribute *attr, char *buf) 204 { 205 struct hl_device *hdev = dev_get_drvdata(dev); 206 long value; 207 208 if (!hl_device_operational(hdev, NULL)) 209 return -ENODEV; 210 211 value = hl_fw_get_frequency(hdev, HL_GOYA_TPC_PLL, true); 212 213 if (value < 0) 214 return value; 215 216 return sprintf(buf, "%lu\n", value); 217 } 218 219 static ssize_t ic_clk_curr_show(struct device *dev, 220 struct device_attribute *attr, char *buf) 221 { 222 struct hl_device *hdev = dev_get_drvdata(dev); 223 long value; 224 225 if (!hl_device_operational(hdev, NULL)) 226 return -ENODEV; 227 228 value = hl_fw_get_frequency(hdev, HL_GOYA_IC_PLL, true); 229 230 if (value < 0) 231 return value; 232 233 return sprintf(buf, "%lu\n", value); 234 } 235 236 static ssize_t pm_mng_profile_show(struct device *dev, 237 struct device_attribute *attr, char *buf) 238 { 239 struct hl_device *hdev = dev_get_drvdata(dev); 240 struct goya_device *goya = hdev->asic_specific; 241 242 if (!hl_device_operational(hdev, NULL)) 243 return -ENODEV; 244 245 return sprintf(buf, "%s\n", 246 (goya->pm_mng_profile == PM_AUTO) ? "auto" : 247 (goya->pm_mng_profile == PM_MANUAL) ? "manual" : 248 "unknown"); 249 } 250 251 static ssize_t pm_mng_profile_store(struct device *dev, 252 struct device_attribute *attr, const char *buf, size_t count) 253 { 254 struct hl_device *hdev = dev_get_drvdata(dev); 255 struct goya_device *goya = hdev->asic_specific; 256 257 if (!hl_device_operational(hdev, NULL)) { 258 count = -ENODEV; 259 goto out; 260 } 261 262 mutex_lock(&hdev->fpriv_list_lock); 263 264 if (hdev->is_compute_ctx_active) { 265 dev_err(hdev->dev, 266 "Can't change PM profile while compute context is opened on the device\n"); 267 count = -EPERM; 268 goto unlock_mutex; 269 } 270 271 if (strncmp("auto", buf, strlen("auto")) == 0) { 272 /* Make sure we are in LOW PLL when changing modes */ 273 if (goya->pm_mng_profile == PM_MANUAL) { 274 goya->curr_pll_profile = PLL_HIGH; 275 goya->pm_mng_profile = PM_AUTO; 276 goya_set_frequency(hdev, PLL_LOW); 277 } 278 } else if (strncmp("manual", buf, strlen("manual")) == 0) { 279 if (goya->pm_mng_profile == PM_AUTO) { 280 /* Must release the lock because the work thread also 281 * takes this lock. But before we release it, set 282 * the mode to manual so nothing will change if a user 283 * suddenly opens the device 284 */ 285 goya->pm_mng_profile = PM_MANUAL; 286 287 mutex_unlock(&hdev->fpriv_list_lock); 288 289 /* Flush the current work so we can return to the user 290 * knowing that he is the only one changing frequencies 291 */ 292 if (goya->goya_work) 293 flush_delayed_work(&goya->goya_work->work_freq); 294 295 return count; 296 } 297 } else { 298 dev_err(hdev->dev, "value should be auto or manual\n"); 299 count = -EINVAL; 300 } 301 302 unlock_mutex: 303 mutex_unlock(&hdev->fpriv_list_lock); 304 out: 305 return count; 306 } 307 308 static ssize_t high_pll_show(struct device *dev, struct device_attribute *attr, 309 char *buf) 310 { 311 struct hl_device *hdev = dev_get_drvdata(dev); 312 313 if (!hl_device_operational(hdev, NULL)) 314 return -ENODEV; 315 316 return sprintf(buf, "%u\n", hdev->high_pll); 317 } 318 319 static ssize_t high_pll_store(struct device *dev, struct device_attribute *attr, 320 const char *buf, size_t count) 321 { 322 struct hl_device *hdev = dev_get_drvdata(dev); 323 long value; 324 int rc; 325 326 if (!hl_device_operational(hdev, NULL)) { 327 count = -ENODEV; 328 goto out; 329 } 330 331 rc = kstrtoul(buf, 0, &value); 332 333 if (rc) { 334 count = -EINVAL; 335 goto out; 336 } 337 338 hdev->high_pll = value; 339 340 out: 341 return count; 342 } 343 344 static DEVICE_ATTR_RW(high_pll); 345 static DEVICE_ATTR_RW(ic_clk); 346 static DEVICE_ATTR_RO(ic_clk_curr); 347 static DEVICE_ATTR_RW(mme_clk); 348 static DEVICE_ATTR_RO(mme_clk_curr); 349 static DEVICE_ATTR_RW(pm_mng_profile); 350 static DEVICE_ATTR_RW(tpc_clk); 351 static DEVICE_ATTR_RO(tpc_clk_curr); 352 353 static struct attribute *goya_clk_dev_attrs[] = { 354 &dev_attr_high_pll.attr, 355 &dev_attr_ic_clk.attr, 356 &dev_attr_ic_clk_curr.attr, 357 &dev_attr_mme_clk.attr, 358 &dev_attr_mme_clk_curr.attr, 359 &dev_attr_pm_mng_profile.attr, 360 &dev_attr_tpc_clk.attr, 361 &dev_attr_tpc_clk_curr.attr, 362 NULL, 363 }; 364 365 static ssize_t infineon_ver_show(struct device *dev, struct device_attribute *attr, char *buf) 366 { 367 struct hl_device *hdev = dev_get_drvdata(dev); 368 struct cpucp_info *cpucp_info; 369 370 cpucp_info = &hdev->asic_prop.cpucp_info; 371 372 return sprintf(buf, "%#04x\n", le32_to_cpu(cpucp_info->infineon_version)); 373 } 374 375 static DEVICE_ATTR_RO(infineon_ver); 376 377 static struct attribute *goya_vrm_dev_attrs[] = { 378 &dev_attr_infineon_ver.attr, 379 NULL, 380 }; 381 382 void goya_add_device_attr(struct hl_device *hdev, struct attribute_group *dev_clk_attr_grp, 383 struct attribute_group *dev_vrm_attr_grp) 384 { 385 dev_clk_attr_grp->attrs = goya_clk_dev_attrs; 386 dev_vrm_attr_grp->attrs = goya_vrm_dev_attrs; 387 } 388