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 
gaudi_set_pll_profile(struct hl_device * hdev,enum hl_pll_frequency freq)11 void 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, MME_PLL, gaudi->max_freq_value);
17 }
18 
gaudi_get_clk_rate(struct hl_device * hdev,u32 * cur_clk,u32 * max_clk)19 int 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, 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, 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 
clk_max_freq_mhz_show(struct device * dev,struct device_attribute * attr,char * buf)50 static 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, MME_PLL, false);
61 
62 	gaudi->max_freq_value = value;
63 
64 	return sprintf(buf, "%lu\n", (value / 1000 / 1000));
65 }
66 
clk_max_freq_mhz_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)67 static 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, MME_PLL, gaudi->max_freq_value);
89 
90 fail:
91 	return count;
92 }
93 
clk_cur_freq_mhz_show(struct device * dev,struct device_attribute * attr,char * buf)94 static 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, MME_PLL, true);
104 
105 	return sprintf(buf, "%lu\n", (value / 1000 / 1000));
106 }
107 
108 static DEVICE_ATTR_RW(clk_max_freq_mhz);
109 static DEVICE_ATTR_RO(clk_cur_freq_mhz);
110 
111 static 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 
gaudi_add_device_attr(struct hl_device * hdev,struct attribute_group * dev_attr_grp)117 void 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