drm/nouveau: consume the return of large GSP message
[drm/drm-misc.git] / drivers / accel / habanalabs / goya / goya_hwmgr.c
blobb595721751c1b5ea857d76e935b8c6b8b01167e3
1 // SPDX-License-Identifier: GPL-2.0
3 /*
4 * Copyright 2016-2022 HabanaLabs, Ltd.
5 * All Rights Reserved.
6 */
8 #include "goyaP.h"
10 void goya_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq)
12 struct goya_device *goya = hdev->asic_specific;
14 if (!hdev->pdev)
15 return;
17 switch (freq) {
18 case PLL_HIGH:
19 hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, hdev->high_pll);
20 hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, hdev->high_pll);
21 hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, hdev->high_pll);
22 break;
23 case PLL_LOW:
24 hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, GOYA_PLL_FREQ_LOW);
25 hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, GOYA_PLL_FREQ_LOW);
26 hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, GOYA_PLL_FREQ_LOW);
27 break;
28 case PLL_LAST:
29 hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, goya->mme_clk);
30 hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, goya->tpc_clk);
31 hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, goya->ic_clk);
32 break;
33 default:
34 dev_err(hdev->dev, "unknown frequency setting\n");
38 static ssize_t mme_clk_show(struct device *dev, struct device_attribute *attr,
39 char *buf)
41 struct hl_device *hdev = dev_get_drvdata(dev);
42 long value;
44 if (!hl_device_operational(hdev, NULL))
45 return -ENODEV;
47 value = hl_fw_get_frequency(hdev, HL_GOYA_MME_PLL, false);
49 if (value < 0)
50 return value;
52 return sprintf(buf, "%lu\n", value);
55 static ssize_t mme_clk_store(struct device *dev, struct device_attribute *attr,
56 const char *buf, size_t count)
58 struct hl_device *hdev = dev_get_drvdata(dev);
59 struct goya_device *goya = hdev->asic_specific;
60 int rc;
61 long value;
63 if (!hl_device_operational(hdev, NULL)) {
64 count = -ENODEV;
65 goto fail;
68 if (goya->pm_mng_profile == PM_AUTO) {
69 count = -EPERM;
70 goto fail;
73 rc = kstrtoul(buf, 0, &value);
75 if (rc) {
76 count = -EINVAL;
77 goto fail;
80 hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, value);
81 goya->mme_clk = value;
83 fail:
84 return count;
87 static ssize_t tpc_clk_show(struct device *dev, struct device_attribute *attr,
88 char *buf)
90 struct hl_device *hdev = dev_get_drvdata(dev);
91 long value;
93 if (!hl_device_operational(hdev, NULL))
94 return -ENODEV;
96 value = hl_fw_get_frequency(hdev, HL_GOYA_TPC_PLL, false);
98 if (value < 0)
99 return value;
101 return sprintf(buf, "%lu\n", value);
104 static ssize_t tpc_clk_store(struct device *dev, struct device_attribute *attr,
105 const char *buf, size_t count)
107 struct hl_device *hdev = dev_get_drvdata(dev);
108 struct goya_device *goya = hdev->asic_specific;
109 int rc;
110 long value;
112 if (!hl_device_operational(hdev, NULL)) {
113 count = -ENODEV;
114 goto fail;
117 if (goya->pm_mng_profile == PM_AUTO) {
118 count = -EPERM;
119 goto fail;
122 rc = kstrtoul(buf, 0, &value);
124 if (rc) {
125 count = -EINVAL;
126 goto fail;
129 hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, value);
130 goya->tpc_clk = value;
132 fail:
133 return count;
136 static ssize_t ic_clk_show(struct device *dev, struct device_attribute *attr,
137 char *buf)
139 struct hl_device *hdev = dev_get_drvdata(dev);
140 long value;
142 if (!hl_device_operational(hdev, NULL))
143 return -ENODEV;
145 value = hl_fw_get_frequency(hdev, HL_GOYA_IC_PLL, false);
147 if (value < 0)
148 return value;
150 return sprintf(buf, "%lu\n", value);
153 static ssize_t ic_clk_store(struct device *dev, struct device_attribute *attr,
154 const char *buf, size_t count)
156 struct hl_device *hdev = dev_get_drvdata(dev);
157 struct goya_device *goya = hdev->asic_specific;
158 int rc;
159 long value;
161 if (!hl_device_operational(hdev, NULL)) {
162 count = -ENODEV;
163 goto fail;
166 if (goya->pm_mng_profile == PM_AUTO) {
167 count = -EPERM;
168 goto fail;
171 rc = kstrtoul(buf, 0, &value);
173 if (rc) {
174 count = -EINVAL;
175 goto fail;
178 hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, value);
179 goya->ic_clk = value;
181 fail:
182 return count;
185 static ssize_t mme_clk_curr_show(struct device *dev,
186 struct device_attribute *attr, char *buf)
188 struct hl_device *hdev = dev_get_drvdata(dev);
189 long value;
191 if (!hl_device_operational(hdev, NULL))
192 return -ENODEV;
194 value = hl_fw_get_frequency(hdev, HL_GOYA_MME_PLL, true);
196 if (value < 0)
197 return value;
199 return sprintf(buf, "%lu\n", value);
202 static ssize_t tpc_clk_curr_show(struct device *dev,
203 struct device_attribute *attr, char *buf)
205 struct hl_device *hdev = dev_get_drvdata(dev);
206 long value;
208 if (!hl_device_operational(hdev, NULL))
209 return -ENODEV;
211 value = hl_fw_get_frequency(hdev, HL_GOYA_TPC_PLL, true);
213 if (value < 0)
214 return value;
216 return sprintf(buf, "%lu\n", value);
219 static ssize_t ic_clk_curr_show(struct device *dev,
220 struct device_attribute *attr, char *buf)
222 struct hl_device *hdev = dev_get_drvdata(dev);
223 long value;
225 if (!hl_device_operational(hdev, NULL))
226 return -ENODEV;
228 value = hl_fw_get_frequency(hdev, HL_GOYA_IC_PLL, true);
230 if (value < 0)
231 return value;
233 return sprintf(buf, "%lu\n", value);
236 static ssize_t pm_mng_profile_show(struct device *dev,
237 struct device_attribute *attr, char *buf)
239 struct hl_device *hdev = dev_get_drvdata(dev);
240 struct goya_device *goya = hdev->asic_specific;
242 if (!hl_device_operational(hdev, NULL))
243 return -ENODEV;
245 return sprintf(buf, "%s\n",
246 (goya->pm_mng_profile == PM_AUTO) ? "auto" :
247 (goya->pm_mng_profile == PM_MANUAL) ? "manual" :
248 "unknown");
251 static ssize_t pm_mng_profile_store(struct device *dev,
252 struct device_attribute *attr, const char *buf, size_t count)
254 struct hl_device *hdev = dev_get_drvdata(dev);
255 struct goya_device *goya = hdev->asic_specific;
257 if (!hl_device_operational(hdev, NULL)) {
258 count = -ENODEV;
259 goto out;
262 mutex_lock(&hdev->fpriv_list_lock);
264 if (hdev->is_compute_ctx_active) {
265 dev_err(hdev->dev,
266 "Can't change PM profile while compute context is opened on the device\n");
267 count = -EPERM;
268 goto unlock_mutex;
271 if (strncmp("auto", buf, strlen("auto")) == 0) {
272 /* Make sure we are in LOW PLL when changing modes */
273 if (goya->pm_mng_profile == PM_MANUAL) {
274 goya->curr_pll_profile = PLL_HIGH;
275 goya->pm_mng_profile = PM_AUTO;
276 goya_set_frequency(hdev, PLL_LOW);
278 } else if (strncmp("manual", buf, strlen("manual")) == 0) {
279 if (goya->pm_mng_profile == PM_AUTO) {
280 /* Must release the lock because the work thread also
281 * takes this lock. But before we release it, set
282 * the mode to manual so nothing will change if a user
283 * suddenly opens the device
285 goya->pm_mng_profile = PM_MANUAL;
287 mutex_unlock(&hdev->fpriv_list_lock);
289 /* Flush the current work so we can return to the user
290 * knowing that he is the only one changing frequencies
292 if (goya->goya_work)
293 flush_delayed_work(&goya->goya_work->work_freq);
295 return count;
297 } else {
298 dev_err(hdev->dev, "value should be auto or manual\n");
299 count = -EINVAL;
302 unlock_mutex:
303 mutex_unlock(&hdev->fpriv_list_lock);
304 out:
305 return count;
308 static ssize_t high_pll_show(struct device *dev, struct device_attribute *attr,
309 char *buf)
311 struct hl_device *hdev = dev_get_drvdata(dev);
313 if (!hl_device_operational(hdev, NULL))
314 return -ENODEV;
316 return sprintf(buf, "%u\n", hdev->high_pll);
319 static ssize_t high_pll_store(struct device *dev, struct device_attribute *attr,
320 const char *buf, size_t count)
322 struct hl_device *hdev = dev_get_drvdata(dev);
323 long value;
324 int rc;
326 if (!hl_device_operational(hdev, NULL)) {
327 count = -ENODEV;
328 goto out;
331 rc = kstrtoul(buf, 0, &value);
333 if (rc) {
334 count = -EINVAL;
335 goto out;
338 hdev->high_pll = value;
340 out:
341 return count;
344 static DEVICE_ATTR_RW(high_pll);
345 static DEVICE_ATTR_RW(ic_clk);
346 static DEVICE_ATTR_RO(ic_clk_curr);
347 static DEVICE_ATTR_RW(mme_clk);
348 static DEVICE_ATTR_RO(mme_clk_curr);
349 static DEVICE_ATTR_RW(pm_mng_profile);
350 static DEVICE_ATTR_RW(tpc_clk);
351 static DEVICE_ATTR_RO(tpc_clk_curr);
353 static struct attribute *goya_clk_dev_attrs[] = {
354 &dev_attr_high_pll.attr,
355 &dev_attr_ic_clk.attr,
356 &dev_attr_ic_clk_curr.attr,
357 &dev_attr_mme_clk.attr,
358 &dev_attr_mme_clk_curr.attr,
359 &dev_attr_pm_mng_profile.attr,
360 &dev_attr_tpc_clk.attr,
361 &dev_attr_tpc_clk_curr.attr,
362 NULL,
365 static ssize_t infineon_ver_show(struct device *dev, struct device_attribute *attr, char *buf)
367 struct hl_device *hdev = dev_get_drvdata(dev);
368 struct cpucp_info *cpucp_info;
370 cpucp_info = &hdev->asic_prop.cpucp_info;
372 return sprintf(buf, "%#04x\n", le32_to_cpu(cpucp_info->infineon_version));
375 static DEVICE_ATTR_RO(infineon_ver);
377 static struct attribute *goya_vrm_dev_attrs[] = {
378 &dev_attr_infineon_ver.attr,
379 NULL,
382 void goya_add_device_attr(struct hl_device *hdev, struct attribute_group *dev_clk_attr_grp,
383 struct attribute_group *dev_vrm_attr_grp)
385 dev_clk_attr_grp->attrs = goya_clk_dev_attrs;
386 dev_vrm_attr_grp->attrs = goya_vrm_dev_attrs;