diff options
author | Oded Gabbay <oded.gabbay@gmail.com> | 2020-05-11 10:41:37 +0300 |
---|---|---|
committer | Oded Gabbay <oded.gabbay@gmail.com> | 2020-05-19 14:48:41 +0300 |
commit | bcaf415204e231be000d76c07f6dde22edabea6a (patch) | |
tree | f5ebcffcb0ce14f8d574ce59acadf931aa955130 /drivers/misc/habanalabs | |
parent | ac0ae6a96aa58eeba4aed97b12ef1dea8c5bf399 (diff) | |
download | linux-bcaf415204e231be000d76c07f6dde22edabea6a.tar.bz2 |
habanalabs: add hwmgr module for gaudi
The hwmgr module is responsible for messages sent to GAUDI F/W that are
not common to all habanalabs ASICs.
In GAUDI, we provide the user a simplified mode of controlling the ASIC
clock frequency. Instead of three different clocks, we present a single
clock property that the user can configure via sysfs.
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
Diffstat (limited to 'drivers/misc/habanalabs')
-rw-r--r-- | drivers/misc/habanalabs/gaudi/Makefile | 2 | ||||
-rw-r--r-- | drivers/misc/habanalabs/gaudi/gaudi.c | 6 | ||||
-rw-r--r-- | drivers/misc/habanalabs/gaudi/gaudiP.h | 5 | ||||
-rw-r--r-- | drivers/misc/habanalabs/gaudi/gaudi_hwmgr.c | 121 |
4 files changed, 130 insertions, 4 deletions
diff --git a/drivers/misc/habanalabs/gaudi/Makefile b/drivers/misc/habanalabs/gaudi/Makefile index b30b523881a0..a7b5be449de3 100644 --- a/drivers/misc/habanalabs/gaudi/Makefile +++ b/drivers/misc/habanalabs/gaudi/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only subdir-ccflags-y += -I$(src) -HL_GAUDI_FILES := gaudi/gaudi.o
\ No newline at end of file +HL_GAUDI_FILES := gaudi/gaudi.o gaudi/gaudi_hwmgr.o
\ No newline at end of file diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index 8f3591e23a3c..c27040f65410 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -7306,9 +7306,9 @@ static const struct hl_asic_funcs gaudi_funcs = { .debugfs_write32 = gaudi_debugfs_write32, .debugfs_read64 = gaudi_debugfs_read64, .debugfs_write64 = gaudi_debugfs_write64, - .add_device_attr = NULL, + .add_device_attr = gaudi_add_device_attr, .handle_eqe = gaudi_handle_eqe, - .set_pll_profile = NULL, + .set_pll_profile = gaudi_set_pll_profile, .get_events_stat = gaudi_get_events_stat, .read_pte = gaudi_read_pte, .write_pte = gaudi_write_pte, @@ -7332,7 +7332,7 @@ static const struct hl_asic_funcs gaudi_funcs = { .rreg = hl_rreg, .wreg = hl_wreg, .halt_coresight = NULL, - .get_clk_rate = NULL, + .get_clk_rate = gaudi_get_clk_rate, .get_queue_id_for_cq = gaudi_get_queue_id_for_cq, .read_device_fw_version = gaudi_read_device_fw_version, .load_firmware_to_device = gaudi_load_firmware_to_device, diff --git a/drivers/misc/habanalabs/gaudi/gaudiP.h b/drivers/misc/habanalabs/gaudi/gaudiP.h index 4fe66b8e1968..f48f4647fbed 100644 --- a/drivers/misc/habanalabs/gaudi/gaudiP.h +++ b/drivers/misc/habanalabs/gaudi/gaudiP.h @@ -248,4 +248,9 @@ struct gaudi_device { u8 ext_queue_idx; }; +void gaudi_add_device_attr(struct hl_device *hdev, + struct attribute_group *dev_attr_grp); +void gaudi_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq); +int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk); + #endif /* GAUDIP_H_ */ diff --git a/drivers/misc/habanalabs/gaudi/gaudi_hwmgr.c b/drivers/misc/habanalabs/gaudi/gaudi_hwmgr.c new file mode 100644 index 000000000000..6dd2c2a1cd70 --- /dev/null +++ b/drivers/misc/habanalabs/gaudi/gaudi_hwmgr.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + */ + +#include "gaudiP.h" +#include "include/gaudi/gaudi_fw_if.h" + +void gaudi_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq) +{ + struct gaudi_device *gaudi = hdev->asic_specific; + + if (freq == PLL_LAST) + hl_set_frequency(hdev, MME_PLL, gaudi->max_freq_value); +} + +int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk) +{ + long value; + + if (hl_device_disabled_or_in_reset(hdev)) + return -ENODEV; + + value = hl_get_frequency(hdev, MME_PLL, 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, MME_PLL, 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); + struct gaudi_device *gaudi = hdev->asic_specific; + long value; + + if (hl_device_disabled_or_in_reset(hdev)) + return -ENODEV; + + value = hl_get_frequency(hdev, MME_PLL, false); + + gaudi->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); + struct gaudi_device *gaudi = hdev->asic_specific; + int rc; + u64 value; + + if (hl_device_disabled_or_in_reset(hdev)) { + count = -ENODEV; + goto fail; + } + + rc = kstrtoull(buf, 0, &value); + if (rc) { + count = -EINVAL; + goto fail; + } + + gaudi->max_freq_value = value * 1000 * 1000; + + hl_set_frequency(hdev, MME_PLL, gaudi->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_disabled_or_in_reset(hdev)) + return -ENODEV; + + value = hl_get_frequency(hdev, MME_PLL, 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 *gaudi_dev_attrs[] = { + &dev_attr_clk_max_freq_mhz.attr, + &dev_attr_clk_cur_freq_mhz.attr, + NULL, +}; + +void gaudi_add_device_attr(struct hl_device *hdev, + struct attribute_group *dev_attr_grp) +{ + dev_attr_grp->attrs = gaudi_dev_attrs; +} |