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