linux/drivers/misc/habanalabs/gaudi/gaudi_hwmgr.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2
   3/*
   4 * Copyright 2016-2018 HabanaLabs, Ltd.
   5 * All Rights Reserved.
   6 */
   7
   8#include "gaudiP.h"
   9#include "../include/gaudi/gaudi_fw_if.h"
  10
  11void gaudi_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq)
  12{
  13        struct gaudi_device *gaudi = hdev->asic_specific;
  14
  15        if (freq == PLL_LAST)
  16                hl_set_frequency(hdev, HL_GAUDI_MME_PLL, gaudi->max_freq_value);
  17}
  18
  19int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk)
  20{
  21        long value;
  22
  23        if (!hl_device_operational(hdev, NULL))
  24                return -ENODEV;
  25
  26        value = hl_get_frequency(hdev, HL_GAUDI_MME_PLL, false);
  27
  28        if (value < 0) {
  29                dev_err(hdev->dev, "Failed to retrieve device max clock %ld\n",
  30                        value);
  31                return value;
  32        }
  33
  34        *max_clk = (value / 1000 / 1000);
  35
  36        value = hl_get_frequency(hdev, HL_GAUDI_MME_PLL, true);
  37
  38        if (value < 0) {
  39                dev_err(hdev->dev,
  40                        "Failed to retrieve device current clock %ld\n",
  41                        value);
  42                return value;
  43        }
  44
  45        *cur_clk = (value / 1000 / 1000);
  46
  47        return 0;
  48}
  49
  50static ssize_t clk_max_freq_mhz_show(struct device *dev,
  51                struct device_attribute *attr, char *buf)
  52{
  53        struct hl_device *hdev = dev_get_drvdata(dev);
  54        struct gaudi_device *gaudi = hdev->asic_specific;
  55        long value;
  56
  57        if (!hl_device_operational(hdev, NULL))
  58                return -ENODEV;
  59
  60        value = hl_get_frequency(hdev, HL_GAUDI_MME_PLL, false);
  61
  62        gaudi->max_freq_value = value;
  63
  64        return sprintf(buf, "%lu\n", (value / 1000 / 1000));
  65}
  66
  67static ssize_t clk_max_freq_mhz_store(struct device *dev,
  68                struct device_attribute *attr, const char *buf, size_t count)
  69{
  70        struct hl_device *hdev = dev_get_drvdata(dev);
  71        struct gaudi_device *gaudi = hdev->asic_specific;
  72        int rc;
  73        u64 value;
  74
  75        if (!hl_device_operational(hdev, NULL)) {
  76                count = -ENODEV;
  77                goto fail;
  78        }
  79
  80        rc = kstrtoull(buf, 0, &value);
  81        if (rc) {
  82                count = -EINVAL;
  83                goto fail;
  84        }
  85
  86        gaudi->max_freq_value = value * 1000 * 1000;
  87
  88        hl_set_frequency(hdev, HL_GAUDI_MME_PLL, gaudi->max_freq_value);
  89
  90fail:
  91        return count;
  92}
  93
  94static ssize_t clk_cur_freq_mhz_show(struct device *dev,
  95                struct device_attribute *attr, char *buf)
  96{
  97        struct hl_device *hdev = dev_get_drvdata(dev);
  98        long value;
  99
 100        if (!hl_device_operational(hdev, NULL))
 101                return -ENODEV;
 102
 103        value = hl_get_frequency(hdev, HL_GAUDI_MME_PLL, true);
 104
 105        return sprintf(buf, "%lu\n", (value / 1000 / 1000));
 106}
 107
 108static DEVICE_ATTR_RW(clk_max_freq_mhz);
 109static DEVICE_ATTR_RO(clk_cur_freq_mhz);
 110
 111static struct attribute *gaudi_dev_attrs[] = {
 112        &dev_attr_clk_max_freq_mhz.attr,
 113        &dev_attr_clk_cur_freq_mhz.attr,
 114        NULL,
 115};
 116
 117void gaudi_add_device_attr(struct hl_device *hdev,
 118                        struct attribute_group *dev_attr_grp)
 119{
 120        dev_attr_grp->attrs = gaudi_dev_attrs;
 121}
 122