diff options
author | Rajaravi Krishna Katta <rkatta@habana.ai> | 2021-09-03 08:01:30 +0300 |
---|---|---|
committer | Oded Gabbay <ogabbay@kernel.org> | 2021-10-18 12:05:47 +0300 |
commit | 024b7b1d6dcd1960e9b669e981968ca4b6bf80cb (patch) | |
tree | 1ebfcf55b6b775306401da234afa1c9136dc3e3c /drivers/misc/habanalabs/common/hwmgr.c | |
parent | f6fb34390cd047543ff00b34b8ad910bf76c8eb3 (diff) |
habanalabs: Unify frequency set/get functionality
Make the frequency set/get functionality common to all ASICs.
This makes more code reusable when adding support for newer ASICs.
Signed-off-by: Rajaravi Krishna Katta <rkatta@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
Diffstat (limited to 'drivers/misc/habanalabs/common/hwmgr.c')
-rw-r--r-- | drivers/misc/habanalabs/common/hwmgr.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/drivers/misc/habanalabs/common/hwmgr.c b/drivers/misc/habanalabs/common/hwmgr.c new file mode 100644 index 000000000000..5451019f143f --- /dev/null +++ b/drivers/misc/habanalabs/common/hwmgr.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Copyright 2019-2021 HabanaLabs, Ltd. + * All Rights Reserved. + */ + +#include "habanalabs.h" + +void hl_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq) +{ + hl_set_frequency(hdev, hdev->asic_prop.clk_pll_index, + hdev->asic_prop.max_freq_value); +} + +int hl_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk) +{ + long value; + + if (!hl_device_operational(hdev, NULL)) + return -ENODEV; + + value = hl_get_frequency(hdev, hdev->asic_prop.clk_pll_index, false); + + if (value < 0) { + dev_err(hdev->dev, "Failed to retrieve device max clock %ld\n", + value); + return value; + } + + *max_clk = (value / 1000 / 1000); + + value = hl_get_frequency(hdev, hdev->asic_prop.clk_pll_index, true); + + if (value < 0) { + dev_err(hdev->dev, + "Failed to retrieve device current clock %ld\n", + value); + return value; + } + + *cur_clk = (value / 1000 / 1000); + + return 0; +} + +static ssize_t clk_max_freq_mhz_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hl_device *hdev = dev_get_drvdata(dev); + long value; + + if (!hl_device_operational(hdev, NULL)) + return -ENODEV; + + value = hl_get_frequency(hdev, hdev->asic_prop.clk_pll_index, false); + + hdev->asic_prop.max_freq_value = value; + + return sprintf(buf, "%lu\n", (value / 1000 / 1000)); +} + +static ssize_t clk_max_freq_mhz_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hl_device *hdev = dev_get_drvdata(dev); + int rc; + u64 value; + + if (!hl_device_operational(hdev, NULL)) { + count = -ENODEV; + goto fail; + } + + rc = kstrtoull(buf, 0, &value); + if (rc) { + count = -EINVAL; + goto fail; + } + + hdev->asic_prop.max_freq_value = value * 1000 * 1000; + + hl_set_frequency(hdev, hdev->asic_prop.clk_pll_index, + hdev->asic_prop.max_freq_value); + +fail: + return count; +} + +static ssize_t clk_cur_freq_mhz_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hl_device *hdev = dev_get_drvdata(dev); + long value; + + if (!hl_device_operational(hdev, NULL)) + return -ENODEV; + + value = hl_get_frequency(hdev, hdev->asic_prop.clk_pll_index, true); + + return sprintf(buf, "%lu\n", (value / 1000 / 1000)); +} + +static DEVICE_ATTR_RW(clk_max_freq_mhz); +static DEVICE_ATTR_RO(clk_cur_freq_mhz); + +static struct attribute *hl_dev_attrs[] = { + &dev_attr_clk_max_freq_mhz.attr, + &dev_attr_clk_cur_freq_mhz.attr, + NULL, +}; + +void hl_add_device_attr(struct hl_device *hdev, + struct attribute_group *dev_attr_grp) +{ + dev_attr_grp->attrs = hl_dev_attrs; +} |