root/drivers/misc/habanalabs/sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hl_get_frequency
  2. hl_set_frequency
  3. hl_get_max_power
  4. hl_set_max_power
  5. uboot_ver_show
  6. armcp_kernel_ver_show
  7. armcp_ver_show
  8. cpld_ver_show
  9. infineon_ver_show
  10. fuse_ver_show
  11. thermal_ver_show
  12. preboot_btl_ver_show
  13. soft_reset_store
  14. hard_reset_store
  15. device_type_show
  16. pci_addr_show
  17. status_show
  18. soft_reset_cnt_show
  19. hard_reset_cnt_show
  20. max_power_show
  21. max_power_store
  22. eeprom_read_handler
  23. hl_sysfs_init
  24. hl_sysfs_fini

   1 // SPDX-License-Identifier: GPL-2.0
   2 
   3 /*
   4  * Copyright 2016-2019 HabanaLabs, Ltd.
   5  * All Rights Reserved.
   6  */
   7 
   8 #include "habanalabs.h"
   9 
  10 #include <linux/pci.h>
  11 
  12 #define SET_CLK_PKT_TIMEOUT     1000000 /* 1s */
  13 #define SET_PWR_PKT_TIMEOUT     1000000 /* 1s */
  14 
  15 long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr)
  16 {
  17         struct armcp_packet pkt;
  18         long result;
  19         int rc;
  20 
  21         memset(&pkt, 0, sizeof(pkt));
  22 
  23         if (curr)
  24                 pkt.ctl = cpu_to_le32(ARMCP_PACKET_FREQUENCY_CURR_GET <<
  25                                                 ARMCP_PKT_CTL_OPCODE_SHIFT);
  26         else
  27                 pkt.ctl = cpu_to_le32(ARMCP_PACKET_FREQUENCY_GET <<
  28                                                 ARMCP_PKT_CTL_OPCODE_SHIFT);
  29         pkt.pll_index = cpu_to_le32(pll_index);
  30 
  31         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  32                                                 SET_CLK_PKT_TIMEOUT, &result);
  33 
  34         if (rc) {
  35                 dev_err(hdev->dev,
  36                         "Failed to get frequency of PLL %d, error %d\n",
  37                         pll_index, rc);
  38                 result = rc;
  39         }
  40 
  41         return result;
  42 }
  43 
  44 void hl_set_frequency(struct hl_device *hdev, u32 pll_index, u64 freq)
  45 {
  46         struct armcp_packet pkt;
  47         int rc;
  48 
  49         memset(&pkt, 0, sizeof(pkt));
  50 
  51         pkt.ctl = cpu_to_le32(ARMCP_PACKET_FREQUENCY_SET <<
  52                                         ARMCP_PKT_CTL_OPCODE_SHIFT);
  53         pkt.pll_index = cpu_to_le32(pll_index);
  54         pkt.value = cpu_to_le64(freq);
  55 
  56         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  57                                         SET_CLK_PKT_TIMEOUT, NULL);
  58 
  59         if (rc)
  60                 dev_err(hdev->dev,
  61                         "Failed to set frequency to PLL %d, error %d\n",
  62                         pll_index, rc);
  63 }
  64 
  65 u64 hl_get_max_power(struct hl_device *hdev)
  66 {
  67         struct armcp_packet pkt;
  68         long result;
  69         int rc;
  70 
  71         memset(&pkt, 0, sizeof(pkt));
  72 
  73         pkt.ctl = cpu_to_le32(ARMCP_PACKET_MAX_POWER_GET <<
  74                                 ARMCP_PKT_CTL_OPCODE_SHIFT);
  75 
  76         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  77                                                 SET_PWR_PKT_TIMEOUT, &result);
  78 
  79         if (rc) {
  80                 dev_err(hdev->dev, "Failed to get max power, error %d\n", rc);
  81                 result = rc;
  82         }
  83 
  84         return result;
  85 }
  86 
  87 void hl_set_max_power(struct hl_device *hdev, u64 value)
  88 {
  89         struct armcp_packet pkt;
  90         int rc;
  91 
  92         memset(&pkt, 0, sizeof(pkt));
  93 
  94         pkt.ctl = cpu_to_le32(ARMCP_PACKET_MAX_POWER_SET <<
  95                                 ARMCP_PKT_CTL_OPCODE_SHIFT);
  96         pkt.value = cpu_to_le64(value);
  97 
  98         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  99                                         SET_PWR_PKT_TIMEOUT, NULL);
 100 
 101         if (rc)
 102                 dev_err(hdev->dev, "Failed to set max power, error %d\n", rc);
 103 }
 104 
 105 static ssize_t uboot_ver_show(struct device *dev, struct device_attribute *attr,
 106                                 char *buf)
 107 {
 108         struct hl_device *hdev = dev_get_drvdata(dev);
 109 
 110         return sprintf(buf, "%s\n", hdev->asic_prop.uboot_ver);
 111 }
 112 
 113 static ssize_t armcp_kernel_ver_show(struct device *dev,
 114                                 struct device_attribute *attr, char *buf)
 115 {
 116         struct hl_device *hdev = dev_get_drvdata(dev);
 117 
 118         return sprintf(buf, "%s", hdev->asic_prop.armcp_info.kernel_version);
 119 }
 120 
 121 static ssize_t armcp_ver_show(struct device *dev, struct device_attribute *attr,
 122                                 char *buf)
 123 {
 124         struct hl_device *hdev = dev_get_drvdata(dev);
 125 
 126         return sprintf(buf, "%s\n", hdev->asic_prop.armcp_info.armcp_version);
 127 }
 128 
 129 static ssize_t cpld_ver_show(struct device *dev, struct device_attribute *attr,
 130                                 char *buf)
 131 {
 132         struct hl_device *hdev = dev_get_drvdata(dev);
 133 
 134         return sprintf(buf, "0x%08x\n",
 135                         hdev->asic_prop.armcp_info.cpld_version);
 136 }
 137 
 138 static ssize_t infineon_ver_show(struct device *dev,
 139                                 struct device_attribute *attr, char *buf)
 140 {
 141         struct hl_device *hdev = dev_get_drvdata(dev);
 142 
 143         return sprintf(buf, "0x%04x\n",
 144                         hdev->asic_prop.armcp_info.infineon_version);
 145 }
 146 
 147 static ssize_t fuse_ver_show(struct device *dev, struct device_attribute *attr,
 148                                 char *buf)
 149 {
 150         struct hl_device *hdev = dev_get_drvdata(dev);
 151 
 152         return sprintf(buf, "%s\n", hdev->asic_prop.armcp_info.fuse_version);
 153 }
 154 
 155 static ssize_t thermal_ver_show(struct device *dev,
 156                                 struct device_attribute *attr, char *buf)
 157 {
 158         struct hl_device *hdev = dev_get_drvdata(dev);
 159 
 160         return sprintf(buf, "%s", hdev->asic_prop.armcp_info.thermal_version);
 161 }
 162 
 163 static ssize_t preboot_btl_ver_show(struct device *dev,
 164                                 struct device_attribute *attr, char *buf)
 165 {
 166         struct hl_device *hdev = dev_get_drvdata(dev);
 167 
 168         return sprintf(buf, "%s\n", hdev->asic_prop.preboot_ver);
 169 }
 170 
 171 static ssize_t soft_reset_store(struct device *dev,
 172                                 struct device_attribute *attr, const char *buf,
 173                                 size_t count)
 174 {
 175         struct hl_device *hdev = dev_get_drvdata(dev);
 176         long value;
 177         int rc;
 178 
 179         rc = kstrtoul(buf, 0, &value);
 180 
 181         if (rc) {
 182                 count = -EINVAL;
 183                 goto out;
 184         }
 185 
 186         hl_device_reset(hdev, false, false);
 187 
 188 out:
 189         return count;
 190 }
 191 
 192 static ssize_t hard_reset_store(struct device *dev,
 193                                 struct device_attribute *attr,
 194                                 const char *buf, size_t count)
 195 {
 196         struct hl_device *hdev = dev_get_drvdata(dev);
 197         long value;
 198         int rc;
 199 
 200         rc = kstrtoul(buf, 0, &value);
 201 
 202         if (rc) {
 203                 count = -EINVAL;
 204                 goto out;
 205         }
 206 
 207         hl_device_reset(hdev, true, false);
 208 
 209 out:
 210         return count;
 211 }
 212 
 213 static ssize_t device_type_show(struct device *dev,
 214                 struct device_attribute *attr, char *buf)
 215 {
 216         struct hl_device *hdev = dev_get_drvdata(dev);
 217         char *str;
 218 
 219         switch (hdev->asic_type) {
 220         case ASIC_GOYA:
 221                 str = "GOYA";
 222                 break;
 223         default:
 224                 dev_err(hdev->dev, "Unrecognized ASIC type %d\n",
 225                                 hdev->asic_type);
 226                 return -EINVAL;
 227         }
 228 
 229         return sprintf(buf, "%s\n", str);
 230 }
 231 
 232 static ssize_t pci_addr_show(struct device *dev, struct device_attribute *attr,
 233                                 char *buf)
 234 {
 235         struct hl_device *hdev = dev_get_drvdata(dev);
 236 
 237         return sprintf(buf, "%04x:%02x:%02x.%x\n",
 238                         pci_domain_nr(hdev->pdev->bus),
 239                         hdev->pdev->bus->number,
 240                         PCI_SLOT(hdev->pdev->devfn),
 241                         PCI_FUNC(hdev->pdev->devfn));
 242 }
 243 
 244 static ssize_t status_show(struct device *dev, struct device_attribute *attr,
 245                                 char *buf)
 246 {
 247         struct hl_device *hdev = dev_get_drvdata(dev);
 248         char *str;
 249 
 250         if (atomic_read(&hdev->in_reset))
 251                 str = "In reset";
 252         else if (hdev->disabled)
 253                 str = "Malfunction";
 254         else
 255                 str = "Operational";
 256 
 257         return sprintf(buf, "%s\n", str);
 258 }
 259 
 260 static ssize_t soft_reset_cnt_show(struct device *dev,
 261                 struct device_attribute *attr, char *buf)
 262 {
 263         struct hl_device *hdev = dev_get_drvdata(dev);
 264 
 265         return sprintf(buf, "%d\n", hdev->soft_reset_cnt);
 266 }
 267 
 268 static ssize_t hard_reset_cnt_show(struct device *dev,
 269                 struct device_attribute *attr, char *buf)
 270 {
 271         struct hl_device *hdev = dev_get_drvdata(dev);
 272 
 273         return sprintf(buf, "%d\n", hdev->hard_reset_cnt);
 274 }
 275 
 276 static ssize_t max_power_show(struct device *dev, struct device_attribute *attr,
 277                                 char *buf)
 278 {
 279         struct hl_device *hdev = dev_get_drvdata(dev);
 280         long val;
 281 
 282         if (hl_device_disabled_or_in_reset(hdev))
 283                 return -ENODEV;
 284 
 285         val = hl_get_max_power(hdev);
 286 
 287         return sprintf(buf, "%lu\n", val);
 288 }
 289 
 290 static ssize_t max_power_store(struct device *dev,
 291                 struct device_attribute *attr, const char *buf, size_t count)
 292 {
 293         struct hl_device *hdev = dev_get_drvdata(dev);
 294         unsigned long value;
 295         int rc;
 296 
 297         if (hl_device_disabled_or_in_reset(hdev)) {
 298                 count = -ENODEV;
 299                 goto out;
 300         }
 301 
 302         rc = kstrtoul(buf, 0, &value);
 303 
 304         if (rc) {
 305                 count = -EINVAL;
 306                 goto out;
 307         }
 308 
 309         hdev->max_power = value;
 310         hl_set_max_power(hdev, value);
 311 
 312 out:
 313         return count;
 314 }
 315 
 316 static ssize_t eeprom_read_handler(struct file *filp, struct kobject *kobj,
 317                         struct bin_attribute *attr, char *buf, loff_t offset,
 318                         size_t max_size)
 319 {
 320         struct device *dev = container_of(kobj, struct device, kobj);
 321         struct hl_device *hdev = dev_get_drvdata(dev);
 322         char *data;
 323         int rc;
 324 
 325         if (!max_size)
 326                 return -EINVAL;
 327 
 328         data = kzalloc(max_size, GFP_KERNEL);
 329         if (!data)
 330                 return -ENOMEM;
 331 
 332         rc = hdev->asic_funcs->get_eeprom_data(hdev, data, max_size);
 333         if (rc)
 334                 goto out;
 335 
 336         memcpy(buf, data, max_size);
 337 
 338 out:
 339         kfree(data);
 340 
 341         return max_size;
 342 }
 343 
 344 static DEVICE_ATTR_RO(armcp_kernel_ver);
 345 static DEVICE_ATTR_RO(armcp_ver);
 346 static DEVICE_ATTR_RO(cpld_ver);
 347 static DEVICE_ATTR_RO(device_type);
 348 static DEVICE_ATTR_RO(fuse_ver);
 349 static DEVICE_ATTR_WO(hard_reset);
 350 static DEVICE_ATTR_RO(hard_reset_cnt);
 351 static DEVICE_ATTR_RO(infineon_ver);
 352 static DEVICE_ATTR_RW(max_power);
 353 static DEVICE_ATTR_RO(pci_addr);
 354 static DEVICE_ATTR_RO(preboot_btl_ver);
 355 static DEVICE_ATTR_WO(soft_reset);
 356 static DEVICE_ATTR_RO(soft_reset_cnt);
 357 static DEVICE_ATTR_RO(status);
 358 static DEVICE_ATTR_RO(thermal_ver);
 359 static DEVICE_ATTR_RO(uboot_ver);
 360 
 361 static struct bin_attribute bin_attr_eeprom = {
 362         .attr = {.name = "eeprom", .mode = (0444)},
 363         .size = PAGE_SIZE,
 364         .read = eeprom_read_handler
 365 };
 366 
 367 static struct attribute *hl_dev_attrs[] = {
 368         &dev_attr_armcp_kernel_ver.attr,
 369         &dev_attr_armcp_ver.attr,
 370         &dev_attr_cpld_ver.attr,
 371         &dev_attr_device_type.attr,
 372         &dev_attr_fuse_ver.attr,
 373         &dev_attr_hard_reset.attr,
 374         &dev_attr_hard_reset_cnt.attr,
 375         &dev_attr_infineon_ver.attr,
 376         &dev_attr_max_power.attr,
 377         &dev_attr_pci_addr.attr,
 378         &dev_attr_preboot_btl_ver.attr,
 379         &dev_attr_soft_reset.attr,
 380         &dev_attr_soft_reset_cnt.attr,
 381         &dev_attr_status.attr,
 382         &dev_attr_thermal_ver.attr,
 383         &dev_attr_uboot_ver.attr,
 384         NULL,
 385 };
 386 
 387 static struct bin_attribute *hl_dev_bin_attrs[] = {
 388         &bin_attr_eeprom,
 389         NULL
 390 };
 391 
 392 static struct attribute_group hl_dev_attr_group = {
 393         .attrs = hl_dev_attrs,
 394         .bin_attrs = hl_dev_bin_attrs,
 395 };
 396 
 397 static struct attribute_group hl_dev_clks_attr_group;
 398 
 399 static const struct attribute_group *hl_dev_attr_groups[] = {
 400         &hl_dev_attr_group,
 401         &hl_dev_clks_attr_group,
 402         NULL,
 403 };
 404 
 405 int hl_sysfs_init(struct hl_device *hdev)
 406 {
 407         int rc;
 408 
 409         hdev->pm_mng_profile = PM_AUTO;
 410         hdev->max_power = hdev->asic_prop.max_power_default;
 411 
 412         hdev->asic_funcs->add_device_attr(hdev, &hl_dev_clks_attr_group);
 413 
 414         rc = device_add_groups(hdev->dev, hl_dev_attr_groups);
 415         if (rc) {
 416                 dev_err(hdev->dev,
 417                         "Failed to add groups to device, error %d\n", rc);
 418                 return rc;
 419         }
 420 
 421         return 0;
 422 }
 423 
 424 void hl_sysfs_fini(struct hl_device *hdev)
 425 {
 426         device_remove_groups(hdev->dev, hl_dev_attr_groups);
 427 }

/* [<][>][^][v][top][bottom][index][help] */