162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci/*
462306a36Sopenharmony_ci * Copyright 2016-2022 HabanaLabs, Ltd.
562306a36Sopenharmony_ci * All Rights Reserved.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "habanalabs.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/pci.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cistatic ssize_t clk_max_freq_mhz_show(struct device *dev, struct device_attribute *attr, char *buf)
1362306a36Sopenharmony_ci{
1462306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
1562306a36Sopenharmony_ci	long value;
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci	if (!hl_device_operational(hdev, NULL))
1862306a36Sopenharmony_ci		return -ENODEV;
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci	value = hl_fw_get_frequency(hdev, hdev->asic_prop.clk_pll_index, false);
2162306a36Sopenharmony_ci	if (value < 0)
2262306a36Sopenharmony_ci		return value;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	hdev->asic_prop.max_freq_value = value;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	return sprintf(buf, "%lu\n", (value / 1000 / 1000));
2762306a36Sopenharmony_ci}
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic ssize_t clk_max_freq_mhz_store(struct device *dev, struct device_attribute *attr,
3062306a36Sopenharmony_ci					const char *buf, size_t count)
3162306a36Sopenharmony_ci{
3262306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
3362306a36Sopenharmony_ci	int rc;
3462306a36Sopenharmony_ci	u64 value;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	if (!hl_device_operational(hdev, NULL)) {
3762306a36Sopenharmony_ci		count = -ENODEV;
3862306a36Sopenharmony_ci		goto fail;
3962306a36Sopenharmony_ci	}
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	rc = kstrtoull(buf, 0, &value);
4262306a36Sopenharmony_ci	if (rc) {
4362306a36Sopenharmony_ci		count = -EINVAL;
4462306a36Sopenharmony_ci		goto fail;
4562306a36Sopenharmony_ci	}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	hdev->asic_prop.max_freq_value = value * 1000 * 1000;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	hl_fw_set_frequency(hdev, hdev->asic_prop.clk_pll_index, hdev->asic_prop.max_freq_value);
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cifail:
5262306a36Sopenharmony_ci	return count;
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic ssize_t clk_cur_freq_mhz_show(struct device *dev, struct device_attribute *attr, char *buf)
5662306a36Sopenharmony_ci{
5762306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
5862306a36Sopenharmony_ci	long value;
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	if (!hl_device_operational(hdev, NULL))
6162306a36Sopenharmony_ci		return -ENODEV;
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	value = hl_fw_get_frequency(hdev, hdev->asic_prop.clk_pll_index, true);
6462306a36Sopenharmony_ci	if (value < 0)
6562306a36Sopenharmony_ci		return value;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	return sprintf(buf, "%lu\n", (value / 1000 / 1000));
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistatic DEVICE_ATTR_RW(clk_max_freq_mhz);
7162306a36Sopenharmony_cistatic DEVICE_ATTR_RO(clk_cur_freq_mhz);
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cistatic struct attribute *hl_dev_clk_attrs[] = {
7462306a36Sopenharmony_ci	&dev_attr_clk_max_freq_mhz.attr,
7562306a36Sopenharmony_ci	&dev_attr_clk_cur_freq_mhz.attr,
7662306a36Sopenharmony_ci	NULL,
7762306a36Sopenharmony_ci};
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cistatic ssize_t vrm_ver_show(struct device *dev, struct device_attribute *attr, char *buf)
8062306a36Sopenharmony_ci{
8162306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
8262306a36Sopenharmony_ci	struct cpucp_info *cpucp_info;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	cpucp_info = &hdev->asic_prop.cpucp_info;
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	if (cpucp_info->infineon_second_stage_version)
8762306a36Sopenharmony_ci		return sprintf(buf, "%#04x %#04x\n", le32_to_cpu(cpucp_info->infineon_version),
8862306a36Sopenharmony_ci				le32_to_cpu(cpucp_info->infineon_second_stage_version));
8962306a36Sopenharmony_ci	else
9062306a36Sopenharmony_ci		return sprintf(buf, "%#04x\n", le32_to_cpu(cpucp_info->infineon_version));
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic DEVICE_ATTR_RO(vrm_ver);
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_cistatic struct attribute *hl_dev_vrm_attrs[] = {
9662306a36Sopenharmony_ci	&dev_attr_vrm_ver.attr,
9762306a36Sopenharmony_ci	NULL,
9862306a36Sopenharmony_ci};
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistatic ssize_t uboot_ver_show(struct device *dev, struct device_attribute *attr,
10162306a36Sopenharmony_ci				char *buf)
10262306a36Sopenharmony_ci{
10362306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	return sprintf(buf, "%s\n", hdev->asic_prop.uboot_ver);
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_cistatic ssize_t armcp_kernel_ver_show(struct device *dev,
10962306a36Sopenharmony_ci				struct device_attribute *attr, char *buf)
11062306a36Sopenharmony_ci{
11162306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.kernel_version);
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistatic ssize_t armcp_ver_show(struct device *dev, struct device_attribute *attr,
11762306a36Sopenharmony_ci				char *buf)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.cpucp_version);
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_cistatic ssize_t cpld_ver_show(struct device *dev, struct device_attribute *attr,
12562306a36Sopenharmony_ci				char *buf)
12662306a36Sopenharmony_ci{
12762306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	return sprintf(buf, "0x%08x\n",
13062306a36Sopenharmony_ci			le32_to_cpu(hdev->asic_prop.cpucp_info.cpld_version));
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistatic ssize_t cpucp_kernel_ver_show(struct device *dev,
13462306a36Sopenharmony_ci				struct device_attribute *attr, char *buf)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.kernel_version);
13962306a36Sopenharmony_ci}
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_cistatic ssize_t cpucp_ver_show(struct device *dev, struct device_attribute *attr,
14262306a36Sopenharmony_ci				char *buf)
14362306a36Sopenharmony_ci{
14462306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.cpucp_version);
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_cistatic ssize_t fuse_ver_show(struct device *dev, struct device_attribute *attr,
15062306a36Sopenharmony_ci				char *buf)
15162306a36Sopenharmony_ci{
15262306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.fuse_version);
15562306a36Sopenharmony_ci}
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_cistatic ssize_t thermal_ver_show(struct device *dev,
15862306a36Sopenharmony_ci				struct device_attribute *attr, char *buf)
15962306a36Sopenharmony_ci{
16062306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.thermal_version);
16362306a36Sopenharmony_ci}
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_cistatic ssize_t fw_os_ver_show(struct device *dev,
16662306a36Sopenharmony_ci				struct device_attribute *attr, char *buf)
16762306a36Sopenharmony_ci{
16862306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.fw_os_version);
17162306a36Sopenharmony_ci}
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cistatic ssize_t preboot_btl_ver_show(struct device *dev,
17462306a36Sopenharmony_ci				struct device_attribute *attr, char *buf)
17562306a36Sopenharmony_ci{
17662306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci	return sprintf(buf, "%s\n", hdev->asic_prop.preboot_ver);
17962306a36Sopenharmony_ci}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_cistatic ssize_t soft_reset_store(struct device *dev,
18262306a36Sopenharmony_ci				struct device_attribute *attr, const char *buf,
18362306a36Sopenharmony_ci				size_t count)
18462306a36Sopenharmony_ci{
18562306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
18662306a36Sopenharmony_ci	long value;
18762306a36Sopenharmony_ci	int rc;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	rc = kstrtoul(buf, 0, &value);
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	if (rc) {
19262306a36Sopenharmony_ci		count = -EINVAL;
19362306a36Sopenharmony_ci		goto out;
19462306a36Sopenharmony_ci	}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	if (!hdev->asic_prop.allow_inference_soft_reset) {
19762306a36Sopenharmony_ci		dev_err(hdev->dev, "Device does not support inference soft-reset\n");
19862306a36Sopenharmony_ci		goto out;
19962306a36Sopenharmony_ci	}
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci	dev_warn(hdev->dev, "Inference Soft-Reset requested through sysfs\n");
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	hl_device_reset(hdev, 0);
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ciout:
20662306a36Sopenharmony_ci	return count;
20762306a36Sopenharmony_ci}
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_cistatic ssize_t hard_reset_store(struct device *dev,
21062306a36Sopenharmony_ci				struct device_attribute *attr,
21162306a36Sopenharmony_ci				const char *buf, size_t count)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
21462306a36Sopenharmony_ci	long value;
21562306a36Sopenharmony_ci	int rc;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	rc = kstrtoul(buf, 0, &value);
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci	if (rc) {
22062306a36Sopenharmony_ci		count = -EINVAL;
22162306a36Sopenharmony_ci		goto out;
22262306a36Sopenharmony_ci	}
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	dev_warn(hdev->dev, "Hard-Reset requested through sysfs\n");
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	hl_device_reset(hdev, HL_DRV_RESET_HARD);
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ciout:
22962306a36Sopenharmony_ci	return count;
23062306a36Sopenharmony_ci}
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_cistatic ssize_t device_type_show(struct device *dev,
23362306a36Sopenharmony_ci		struct device_attribute *attr, char *buf)
23462306a36Sopenharmony_ci{
23562306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
23662306a36Sopenharmony_ci	char *str;
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	switch (hdev->asic_type) {
23962306a36Sopenharmony_ci	case ASIC_GOYA:
24062306a36Sopenharmony_ci		str = "GOYA";
24162306a36Sopenharmony_ci		break;
24262306a36Sopenharmony_ci	case ASIC_GAUDI:
24362306a36Sopenharmony_ci		str = "GAUDI";
24462306a36Sopenharmony_ci		break;
24562306a36Sopenharmony_ci	case ASIC_GAUDI_SEC:
24662306a36Sopenharmony_ci		str = "GAUDI SEC";
24762306a36Sopenharmony_ci		break;
24862306a36Sopenharmony_ci	case ASIC_GAUDI2:
24962306a36Sopenharmony_ci		str = "GAUDI2";
25062306a36Sopenharmony_ci		break;
25162306a36Sopenharmony_ci	case ASIC_GAUDI2B:
25262306a36Sopenharmony_ci		str = "GAUDI2B";
25362306a36Sopenharmony_ci		break;
25462306a36Sopenharmony_ci	case ASIC_GAUDI2C:
25562306a36Sopenharmony_ci		str = "GAUDI2C";
25662306a36Sopenharmony_ci		break;
25762306a36Sopenharmony_ci	default:
25862306a36Sopenharmony_ci		dev_err(hdev->dev, "Unrecognized ASIC type %d\n",
25962306a36Sopenharmony_ci				hdev->asic_type);
26062306a36Sopenharmony_ci		return -EINVAL;
26162306a36Sopenharmony_ci	}
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	return sprintf(buf, "%s\n", str);
26462306a36Sopenharmony_ci}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_cistatic ssize_t pci_addr_show(struct device *dev, struct device_attribute *attr,
26762306a36Sopenharmony_ci				char *buf)
26862306a36Sopenharmony_ci{
26962306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci	return sprintf(buf, "%04x:%02x:%02x.%x\n",
27262306a36Sopenharmony_ci			pci_domain_nr(hdev->pdev->bus),
27362306a36Sopenharmony_ci			hdev->pdev->bus->number,
27462306a36Sopenharmony_ci			PCI_SLOT(hdev->pdev->devfn),
27562306a36Sopenharmony_ci			PCI_FUNC(hdev->pdev->devfn));
27662306a36Sopenharmony_ci}
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_cistatic ssize_t status_show(struct device *dev, struct device_attribute *attr,
27962306a36Sopenharmony_ci				char *buf)
28062306a36Sopenharmony_ci{
28162306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
28262306a36Sopenharmony_ci	char str[HL_STR_MAX];
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	strscpy(str, hdev->status[hl_device_status(hdev)], HL_STR_MAX);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	/* use uppercase for backward compatibility */
28762306a36Sopenharmony_ci	str[0] = 'A' + (str[0] - 'a');
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	return sprintf(buf, "%s\n", str);
29062306a36Sopenharmony_ci}
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_cistatic ssize_t soft_reset_cnt_show(struct device *dev,
29362306a36Sopenharmony_ci		struct device_attribute *attr, char *buf)
29462306a36Sopenharmony_ci{
29562306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	return sprintf(buf, "%d\n", hdev->reset_info.compute_reset_cnt);
29862306a36Sopenharmony_ci}
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_cistatic ssize_t hard_reset_cnt_show(struct device *dev,
30162306a36Sopenharmony_ci		struct device_attribute *attr, char *buf)
30262306a36Sopenharmony_ci{
30362306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	return sprintf(buf, "%d\n", hdev->reset_info.hard_reset_cnt);
30662306a36Sopenharmony_ci}
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_cistatic ssize_t max_power_show(struct device *dev, struct device_attribute *attr,
30962306a36Sopenharmony_ci				char *buf)
31062306a36Sopenharmony_ci{
31162306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
31262306a36Sopenharmony_ci	long val;
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci	if (!hl_device_operational(hdev, NULL))
31562306a36Sopenharmony_ci		return -ENODEV;
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	val = hl_fw_get_max_power(hdev);
31862306a36Sopenharmony_ci	if (val < 0)
31962306a36Sopenharmony_ci		return val;
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	return sprintf(buf, "%lu\n", val);
32262306a36Sopenharmony_ci}
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_cistatic ssize_t max_power_store(struct device *dev,
32562306a36Sopenharmony_ci		struct device_attribute *attr, const char *buf, size_t count)
32662306a36Sopenharmony_ci{
32762306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
32862306a36Sopenharmony_ci	unsigned long value;
32962306a36Sopenharmony_ci	int rc;
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	if (!hl_device_operational(hdev, NULL)) {
33262306a36Sopenharmony_ci		count = -ENODEV;
33362306a36Sopenharmony_ci		goto out;
33462306a36Sopenharmony_ci	}
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	rc = kstrtoul(buf, 0, &value);
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci	if (rc) {
33962306a36Sopenharmony_ci		count = -EINVAL;
34062306a36Sopenharmony_ci		goto out;
34162306a36Sopenharmony_ci	}
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	hdev->max_power = value;
34462306a36Sopenharmony_ci	hl_fw_set_max_power(hdev);
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ciout:
34762306a36Sopenharmony_ci	return count;
34862306a36Sopenharmony_ci}
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_cistatic ssize_t eeprom_read_handler(struct file *filp, struct kobject *kobj,
35162306a36Sopenharmony_ci			struct bin_attribute *attr, char *buf, loff_t offset,
35262306a36Sopenharmony_ci			size_t max_size)
35362306a36Sopenharmony_ci{
35462306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
35562306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
35662306a36Sopenharmony_ci	char *data;
35762306a36Sopenharmony_ci	int rc;
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	if (!hl_device_operational(hdev, NULL))
36062306a36Sopenharmony_ci		return -ENODEV;
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci	if (!max_size)
36362306a36Sopenharmony_ci		return -EINVAL;
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	data = kzalloc(max_size, GFP_KERNEL);
36662306a36Sopenharmony_ci	if (!data)
36762306a36Sopenharmony_ci		return -ENOMEM;
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	rc = hdev->asic_funcs->get_eeprom_data(hdev, data, max_size);
37062306a36Sopenharmony_ci	if (rc)
37162306a36Sopenharmony_ci		goto out;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	memcpy(buf, data, max_size);
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ciout:
37662306a36Sopenharmony_ci	kfree(data);
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci	return max_size;
37962306a36Sopenharmony_ci}
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_cistatic ssize_t security_enabled_show(struct device *dev,
38262306a36Sopenharmony_ci				struct device_attribute *attr, char *buf)
38362306a36Sopenharmony_ci{
38462306a36Sopenharmony_ci	struct hl_device *hdev = dev_get_drvdata(dev);
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci	return sprintf(buf, "%d\n", hdev->asic_prop.fw_security_enabled);
38762306a36Sopenharmony_ci}
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_cistatic DEVICE_ATTR_RO(armcp_kernel_ver);
39062306a36Sopenharmony_cistatic DEVICE_ATTR_RO(armcp_ver);
39162306a36Sopenharmony_cistatic DEVICE_ATTR_RO(cpld_ver);
39262306a36Sopenharmony_cistatic DEVICE_ATTR_RO(cpucp_kernel_ver);
39362306a36Sopenharmony_cistatic DEVICE_ATTR_RO(cpucp_ver);
39462306a36Sopenharmony_cistatic DEVICE_ATTR_RO(device_type);
39562306a36Sopenharmony_cistatic DEVICE_ATTR_RO(fuse_ver);
39662306a36Sopenharmony_cistatic DEVICE_ATTR_WO(hard_reset);
39762306a36Sopenharmony_cistatic DEVICE_ATTR_RO(hard_reset_cnt);
39862306a36Sopenharmony_cistatic DEVICE_ATTR_RW(max_power);
39962306a36Sopenharmony_cistatic DEVICE_ATTR_RO(pci_addr);
40062306a36Sopenharmony_cistatic DEVICE_ATTR_RO(preboot_btl_ver);
40162306a36Sopenharmony_cistatic DEVICE_ATTR_WO(soft_reset);
40262306a36Sopenharmony_cistatic DEVICE_ATTR_RO(soft_reset_cnt);
40362306a36Sopenharmony_cistatic DEVICE_ATTR_RO(status);
40462306a36Sopenharmony_cistatic DEVICE_ATTR_RO(thermal_ver);
40562306a36Sopenharmony_cistatic DEVICE_ATTR_RO(uboot_ver);
40662306a36Sopenharmony_cistatic DEVICE_ATTR_RO(fw_os_ver);
40762306a36Sopenharmony_cistatic DEVICE_ATTR_RO(security_enabled);
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_cistatic struct bin_attribute bin_attr_eeprom = {
41062306a36Sopenharmony_ci	.attr = {.name = "eeprom", .mode = (0444)},
41162306a36Sopenharmony_ci	.size = PAGE_SIZE,
41262306a36Sopenharmony_ci	.read = eeprom_read_handler
41362306a36Sopenharmony_ci};
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_cistatic struct attribute *hl_dev_attrs[] = {
41662306a36Sopenharmony_ci	&dev_attr_armcp_kernel_ver.attr,
41762306a36Sopenharmony_ci	&dev_attr_armcp_ver.attr,
41862306a36Sopenharmony_ci	&dev_attr_cpld_ver.attr,
41962306a36Sopenharmony_ci	&dev_attr_cpucp_kernel_ver.attr,
42062306a36Sopenharmony_ci	&dev_attr_cpucp_ver.attr,
42162306a36Sopenharmony_ci	&dev_attr_device_type.attr,
42262306a36Sopenharmony_ci	&dev_attr_fuse_ver.attr,
42362306a36Sopenharmony_ci	&dev_attr_hard_reset.attr,
42462306a36Sopenharmony_ci	&dev_attr_hard_reset_cnt.attr,
42562306a36Sopenharmony_ci	&dev_attr_max_power.attr,
42662306a36Sopenharmony_ci	&dev_attr_pci_addr.attr,
42762306a36Sopenharmony_ci	&dev_attr_preboot_btl_ver.attr,
42862306a36Sopenharmony_ci	&dev_attr_status.attr,
42962306a36Sopenharmony_ci	&dev_attr_thermal_ver.attr,
43062306a36Sopenharmony_ci	&dev_attr_uboot_ver.attr,
43162306a36Sopenharmony_ci	&dev_attr_fw_os_ver.attr,
43262306a36Sopenharmony_ci	&dev_attr_security_enabled.attr,
43362306a36Sopenharmony_ci	NULL,
43462306a36Sopenharmony_ci};
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_cistatic struct bin_attribute *hl_dev_bin_attrs[] = {
43762306a36Sopenharmony_ci	&bin_attr_eeprom,
43862306a36Sopenharmony_ci	NULL
43962306a36Sopenharmony_ci};
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_cistatic struct attribute_group hl_dev_attr_group = {
44262306a36Sopenharmony_ci	.attrs = hl_dev_attrs,
44362306a36Sopenharmony_ci	.bin_attrs = hl_dev_bin_attrs,
44462306a36Sopenharmony_ci};
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_cistatic struct attribute_group hl_dev_clks_attr_group;
44762306a36Sopenharmony_cistatic struct attribute_group hl_dev_vrm_attr_group;
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_cistatic const struct attribute_group *hl_dev_attr_groups[] = {
45062306a36Sopenharmony_ci	&hl_dev_attr_group,
45162306a36Sopenharmony_ci	&hl_dev_clks_attr_group,
45262306a36Sopenharmony_ci	&hl_dev_vrm_attr_group,
45362306a36Sopenharmony_ci	NULL,
45462306a36Sopenharmony_ci};
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_cistatic struct attribute *hl_dev_inference_attrs[] = {
45762306a36Sopenharmony_ci	&dev_attr_soft_reset.attr,
45862306a36Sopenharmony_ci	&dev_attr_soft_reset_cnt.attr,
45962306a36Sopenharmony_ci	NULL,
46062306a36Sopenharmony_ci};
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_cistatic struct attribute_group hl_dev_inference_attr_group = {
46362306a36Sopenharmony_ci	.attrs = hl_dev_inference_attrs,
46462306a36Sopenharmony_ci};
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_cistatic const struct attribute_group *hl_dev_inference_attr_groups[] = {
46762306a36Sopenharmony_ci	&hl_dev_inference_attr_group,
46862306a36Sopenharmony_ci	NULL,
46962306a36Sopenharmony_ci};
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_civoid hl_sysfs_add_dev_clk_attr(struct hl_device *hdev, struct attribute_group *dev_clk_attr_grp)
47262306a36Sopenharmony_ci{
47362306a36Sopenharmony_ci	dev_clk_attr_grp->attrs = hl_dev_clk_attrs;
47462306a36Sopenharmony_ci}
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_civoid hl_sysfs_add_dev_vrm_attr(struct hl_device *hdev, struct attribute_group *dev_vrm_attr_grp)
47762306a36Sopenharmony_ci{
47862306a36Sopenharmony_ci	dev_vrm_attr_grp->attrs = hl_dev_vrm_attrs;
47962306a36Sopenharmony_ci}
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ciint hl_sysfs_init(struct hl_device *hdev)
48262306a36Sopenharmony_ci{
48362306a36Sopenharmony_ci	int rc;
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	hdev->max_power = hdev->asic_prop.max_power_default;
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	hdev->asic_funcs->add_device_attr(hdev, &hl_dev_clks_attr_group, &hl_dev_vrm_attr_group);
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	rc = device_add_groups(hdev->dev, hl_dev_attr_groups);
49062306a36Sopenharmony_ci	if (rc) {
49162306a36Sopenharmony_ci		dev_err(hdev->dev,
49262306a36Sopenharmony_ci			"Failed to add groups to device, error %d\n", rc);
49362306a36Sopenharmony_ci		return rc;
49462306a36Sopenharmony_ci	}
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci	if (!hdev->asic_prop.allow_inference_soft_reset)
49762306a36Sopenharmony_ci		return 0;
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci	rc = device_add_groups(hdev->dev, hl_dev_inference_attr_groups);
50062306a36Sopenharmony_ci	if (rc) {
50162306a36Sopenharmony_ci		dev_err(hdev->dev,
50262306a36Sopenharmony_ci			"Failed to add groups to device, error %d\n", rc);
50362306a36Sopenharmony_ci		goto remove_groups;
50462306a36Sopenharmony_ci	}
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	return 0;
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ciremove_groups:
50962306a36Sopenharmony_ci	device_remove_groups(hdev->dev, hl_dev_attr_groups);
51062306a36Sopenharmony_ci	return rc;
51162306a36Sopenharmony_ci}
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_civoid hl_sysfs_fini(struct hl_device *hdev)
51462306a36Sopenharmony_ci{
51562306a36Sopenharmony_ci	device_remove_groups(hdev->dev, hl_dev_attr_groups);
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	if (!hdev->asic_prop.allow_inference_soft_reset)
51862306a36Sopenharmony_ci		return;
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci	device_remove_groups(hdev->dev, hl_dev_inference_attr_groups);
52162306a36Sopenharmony_ci}
522