1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright 2016-2019 HabanaLabs, Ltd.
10 void goya_set_pll_profile(struct hl_device
*hdev
, enum hl_pll_frequency freq
)
12 struct goya_device
*goya
= hdev
->asic_specific
;
16 hl_set_frequency(hdev
, MME_PLL
, hdev
->high_pll
);
17 hl_set_frequency(hdev
, TPC_PLL
, hdev
->high_pll
);
18 hl_set_frequency(hdev
, IC_PLL
, hdev
->high_pll
);
21 hl_set_frequency(hdev
, MME_PLL
, GOYA_PLL_FREQ_LOW
);
22 hl_set_frequency(hdev
, TPC_PLL
, GOYA_PLL_FREQ_LOW
);
23 hl_set_frequency(hdev
, IC_PLL
, GOYA_PLL_FREQ_LOW
);
26 hl_set_frequency(hdev
, MME_PLL
, goya
->mme_clk
);
27 hl_set_frequency(hdev
, TPC_PLL
, goya
->tpc_clk
);
28 hl_set_frequency(hdev
, IC_PLL
, goya
->ic_clk
);
31 dev_err(hdev
->dev
, "unknown frequency setting\n");
35 int goya_get_clk_rate(struct hl_device
*hdev
, u32
*cur_clk
, u32
*max_clk
)
39 if (!hl_device_operational(hdev
, NULL
))
42 value
= hl_get_frequency(hdev
, MME_PLL
, false);
45 dev_err(hdev
->dev
, "Failed to retrieve device max clock %ld\n",
50 *max_clk
= (value
/ 1000 / 1000);
52 value
= hl_get_frequency(hdev
, MME_PLL
, true);
56 "Failed to retrieve device current clock %ld\n",
61 *cur_clk
= (value
/ 1000 / 1000);
66 static ssize_t
mme_clk_show(struct device
*dev
, struct device_attribute
*attr
,
69 struct hl_device
*hdev
= dev_get_drvdata(dev
);
72 if (!hl_device_operational(hdev
, NULL
))
75 value
= hl_get_frequency(hdev
, MME_PLL
, false);
80 return sprintf(buf
, "%lu\n", value
);
83 static ssize_t
mme_clk_store(struct device
*dev
, struct device_attribute
*attr
,
84 const char *buf
, size_t count
)
86 struct hl_device
*hdev
= dev_get_drvdata(dev
);
87 struct goya_device
*goya
= hdev
->asic_specific
;
91 if (!hl_device_operational(hdev
, NULL
)) {
96 if (hdev
->pm_mng_profile
== PM_AUTO
) {
101 rc
= kstrtoul(buf
, 0, &value
);
108 hl_set_frequency(hdev
, MME_PLL
, value
);
109 goya
->mme_clk
= value
;
115 static ssize_t
tpc_clk_show(struct device
*dev
, struct device_attribute
*attr
,
118 struct hl_device
*hdev
= dev_get_drvdata(dev
);
121 if (!hl_device_operational(hdev
, NULL
))
124 value
= hl_get_frequency(hdev
, TPC_PLL
, false);
129 return sprintf(buf
, "%lu\n", value
);
132 static ssize_t
tpc_clk_store(struct device
*dev
, struct device_attribute
*attr
,
133 const char *buf
, size_t count
)
135 struct hl_device
*hdev
= dev_get_drvdata(dev
);
136 struct goya_device
*goya
= hdev
->asic_specific
;
140 if (!hl_device_operational(hdev
, NULL
)) {
145 if (hdev
->pm_mng_profile
== PM_AUTO
) {
150 rc
= kstrtoul(buf
, 0, &value
);
157 hl_set_frequency(hdev
, TPC_PLL
, value
);
158 goya
->tpc_clk
= value
;
164 static ssize_t
ic_clk_show(struct device
*dev
, struct device_attribute
*attr
,
167 struct hl_device
*hdev
= dev_get_drvdata(dev
);
170 if (!hl_device_operational(hdev
, NULL
))
173 value
= hl_get_frequency(hdev
, IC_PLL
, false);
178 return sprintf(buf
, "%lu\n", value
);
181 static ssize_t
ic_clk_store(struct device
*dev
, struct device_attribute
*attr
,
182 const char *buf
, size_t count
)
184 struct hl_device
*hdev
= dev_get_drvdata(dev
);
185 struct goya_device
*goya
= hdev
->asic_specific
;
189 if (!hl_device_operational(hdev
, NULL
)) {
194 if (hdev
->pm_mng_profile
== PM_AUTO
) {
199 rc
= kstrtoul(buf
, 0, &value
);
206 hl_set_frequency(hdev
, IC_PLL
, value
);
207 goya
->ic_clk
= value
;
213 static ssize_t
mme_clk_curr_show(struct device
*dev
,
214 struct device_attribute
*attr
, char *buf
)
216 struct hl_device
*hdev
= dev_get_drvdata(dev
);
219 if (!hl_device_operational(hdev
, NULL
))
222 value
= hl_get_frequency(hdev
, MME_PLL
, true);
227 return sprintf(buf
, "%lu\n", value
);
230 static ssize_t
tpc_clk_curr_show(struct device
*dev
,
231 struct device_attribute
*attr
, char *buf
)
233 struct hl_device
*hdev
= dev_get_drvdata(dev
);
236 if (!hl_device_operational(hdev
, NULL
))
239 value
= hl_get_frequency(hdev
, TPC_PLL
, true);
244 return sprintf(buf
, "%lu\n", value
);
247 static ssize_t
ic_clk_curr_show(struct device
*dev
,
248 struct device_attribute
*attr
, char *buf
)
250 struct hl_device
*hdev
= dev_get_drvdata(dev
);
253 if (!hl_device_operational(hdev
, NULL
))
256 value
= hl_get_frequency(hdev
, IC_PLL
, true);
261 return sprintf(buf
, "%lu\n", value
);
264 static ssize_t
pm_mng_profile_show(struct device
*dev
,
265 struct device_attribute
*attr
, char *buf
)
267 struct hl_device
*hdev
= dev_get_drvdata(dev
);
269 if (!hl_device_operational(hdev
, NULL
))
272 return sprintf(buf
, "%s\n",
273 (hdev
->pm_mng_profile
== PM_AUTO
) ? "auto" :
274 (hdev
->pm_mng_profile
== PM_MANUAL
) ? "manual" :
278 static ssize_t
pm_mng_profile_store(struct device
*dev
,
279 struct device_attribute
*attr
, const char *buf
, size_t count
)
281 struct hl_device
*hdev
= dev_get_drvdata(dev
);
283 if (!hl_device_operational(hdev
, NULL
)) {
288 mutex_lock(&hdev
->fpriv_list_lock
);
290 if (hdev
->compute_ctx
) {
292 "Can't change PM profile while compute context is opened on the device\n");
297 if (strncmp("auto", buf
, strlen("auto")) == 0) {
298 /* Make sure we are in LOW PLL when changing modes */
299 if (hdev
->pm_mng_profile
== PM_MANUAL
) {
300 hdev
->curr_pll_profile
= PLL_HIGH
;
301 hdev
->pm_mng_profile
= PM_AUTO
;
302 hl_device_set_frequency(hdev
, PLL_LOW
);
304 } else if (strncmp("manual", buf
, strlen("manual")) == 0) {
305 if (hdev
->pm_mng_profile
== PM_AUTO
) {
306 /* Must release the lock because the work thread also
307 * takes this lock. But before we release it, set
308 * the mode to manual so nothing will change if a user
309 * suddenly opens the device
311 hdev
->pm_mng_profile
= PM_MANUAL
;
313 mutex_unlock(&hdev
->fpriv_list_lock
);
315 /* Flush the current work so we can return to the user
316 * knowing that he is the only one changing frequencies
318 flush_delayed_work(&hdev
->work_freq
);
323 dev_err(hdev
->dev
, "value should be auto or manual\n");
328 mutex_unlock(&hdev
->fpriv_list_lock
);
333 static ssize_t
high_pll_show(struct device
*dev
, struct device_attribute
*attr
,
336 struct hl_device
*hdev
= dev_get_drvdata(dev
);
338 if (!hl_device_operational(hdev
, NULL
))
341 return sprintf(buf
, "%u\n", hdev
->high_pll
);
344 static ssize_t
high_pll_store(struct device
*dev
, struct device_attribute
*attr
,
345 const char *buf
, size_t count
)
347 struct hl_device
*hdev
= dev_get_drvdata(dev
);
351 if (!hl_device_operational(hdev
, NULL
)) {
356 rc
= kstrtoul(buf
, 0, &value
);
363 hdev
->high_pll
= value
;
369 static DEVICE_ATTR_RW(high_pll
);
370 static DEVICE_ATTR_RW(ic_clk
);
371 static DEVICE_ATTR_RO(ic_clk_curr
);
372 static DEVICE_ATTR_RW(mme_clk
);
373 static DEVICE_ATTR_RO(mme_clk_curr
);
374 static DEVICE_ATTR_RW(pm_mng_profile
);
375 static DEVICE_ATTR_RW(tpc_clk
);
376 static DEVICE_ATTR_RO(tpc_clk_curr
);
378 static struct attribute
*goya_dev_attrs
[] = {
379 &dev_attr_high_pll
.attr
,
380 &dev_attr_ic_clk
.attr
,
381 &dev_attr_ic_clk_curr
.attr
,
382 &dev_attr_mme_clk
.attr
,
383 &dev_attr_mme_clk_curr
.attr
,
384 &dev_attr_pm_mng_profile
.attr
,
385 &dev_attr_tpc_clk
.attr
,
386 &dev_attr_tpc_clk_curr
.attr
,
390 void goya_add_device_attr(struct hl_device
*hdev
,
391 struct attribute_group
*dev_attr_grp
)
393 dev_attr_grp
->attrs
= goya_dev_attrs
;