2 * Copyright 2013 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
26 #include <subdev/bios.h>
27 #include <subdev/bios/boost.h>
28 #include <subdev/bios/cstep.h>
29 #include <subdev/bios/perf.h>
30 #include <subdev/bios/vpstate.h>
31 #include <subdev/fb.h>
32 #include <subdev/therm.h>
33 #include <subdev/volt.h>
35 #include <core/option.h>
37 /******************************************************************************
39 *****************************************************************************/
41 nvkm_clk_adjust(struct nvkm_clk
*clk
, bool adjust
,
42 u8 pstate
, u8 domain
, u32 input
)
44 struct nvkm_bios
*bios
= clk
->subdev
.device
->bios
;
45 struct nvbios_boostE boostE
;
46 u8 ver
, hdr
, cnt
, len
;
49 data
= nvbios_boostEm(bios
, pstate
, &ver
, &hdr
, &cnt
, &len
, &boostE
);
51 struct nvbios_boostS boostS
;
52 u8 idx
= 0, sver
, shdr
;
55 input
= max(boostE
.min
, input
);
56 input
= min(boostE
.max
, input
);
60 subd
= nvbios_boostSp(bios
, idx
++, data
, &sver
, &shdr
,
62 if (subd
&& boostS
.domain
== domain
) {
64 input
= input
* boostS
.percent
/ 100;
65 input
= max(boostS
.min
, input
);
66 input
= min(boostS
.max
, input
);
75 /******************************************************************************
77 *****************************************************************************/
79 nvkm_cstate_valid(struct nvkm_clk
*clk
, struct nvkm_cstate
*cstate
,
80 u32 max_volt
, int temp
)
82 const struct nvkm_domain
*domain
= clk
->domains
;
83 struct nvkm_volt
*volt
= clk
->subdev
.device
->volt
;
86 while (domain
&& domain
->name
!= nv_clk_src_max
) {
87 if (domain
->flags
& NVKM_CLK_DOM_FLAG_VPSTATE
) {
88 u32 freq
= cstate
->domain
[domain
->name
];
89 switch (clk
->boost_mode
) {
90 case NVKM_CLK_BOOST_NONE
:
91 if (clk
->base_khz
&& freq
> clk
->base_khz
)
94 case NVKM_CLK_BOOST_BIOS
:
95 if (clk
->boost_khz
&& freq
> clk
->boost_khz
)
105 voltage
= nvkm_volt_map(volt
, cstate
->voltage
, temp
);
108 return voltage
<= min(max_volt
, volt
->max_uv
);
111 static struct nvkm_cstate
*
112 nvkm_cstate_find_best(struct nvkm_clk
*clk
, struct nvkm_pstate
*pstate
,
113 struct nvkm_cstate
*cstate
)
115 struct nvkm_device
*device
= clk
->subdev
.device
;
116 struct nvkm_volt
*volt
= device
->volt
;
119 if (!pstate
|| !cstate
)
125 max_volt
= volt
->max_uv
;
126 if (volt
->max0_id
!= 0xff)
127 max_volt
= min(max_volt
,
128 nvkm_volt_map(volt
, volt
->max0_id
, clk
->temp
));
129 if (volt
->max1_id
!= 0xff)
130 max_volt
= min(max_volt
,
131 nvkm_volt_map(volt
, volt
->max1_id
, clk
->temp
));
132 if (volt
->max2_id
!= 0xff)
133 max_volt
= min(max_volt
,
134 nvkm_volt_map(volt
, volt
->max2_id
, clk
->temp
));
136 list_for_each_entry_from_reverse(cstate
, &pstate
->list
, head
) {
137 if (nvkm_cstate_valid(clk
, cstate
, max_volt
, clk
->temp
))
144 static struct nvkm_cstate
*
145 nvkm_cstate_get(struct nvkm_clk
*clk
, struct nvkm_pstate
*pstate
, int cstatei
)
147 struct nvkm_cstate
*cstate
;
148 if (cstatei
== NVKM_CLK_CSTATE_HIGHEST
)
149 return list_last_entry(&pstate
->list
, typeof(*cstate
), head
);
151 list_for_each_entry(cstate
, &pstate
->list
, head
) {
152 if (cstate
->id
== cstatei
)
160 nvkm_cstate_prog(struct nvkm_clk
*clk
, struct nvkm_pstate
*pstate
, int cstatei
)
162 struct nvkm_subdev
*subdev
= &clk
->subdev
;
163 struct nvkm_device
*device
= subdev
->device
;
164 struct nvkm_therm
*therm
= device
->therm
;
165 struct nvkm_volt
*volt
= device
->volt
;
166 struct nvkm_cstate
*cstate
;
169 if (!list_empty(&pstate
->list
)) {
170 cstate
= nvkm_cstate_get(clk
, pstate
, cstatei
);
171 cstate
= nvkm_cstate_find_best(clk
, pstate
, cstate
);
173 cstate
= &pstate
->base
;
177 ret
= nvkm_therm_cstate(therm
, pstate
->fanspeed
, +1);
178 if (ret
&& ret
!= -ENODEV
) {
179 nvkm_error(subdev
, "failed to raise fan speed: %d\n", ret
);
185 ret
= nvkm_volt_set_id(volt
, cstate
->voltage
,
186 pstate
->base
.voltage
, clk
->temp
, +1);
187 if (ret
&& ret
!= -ENODEV
) {
188 nvkm_error(subdev
, "failed to raise voltage: %d\n", ret
);
193 ret
= clk
->func
->calc(clk
, cstate
);
195 ret
= clk
->func
->prog(clk
);
196 clk
->func
->tidy(clk
);
200 ret
= nvkm_volt_set_id(volt
, cstate
->voltage
,
201 pstate
->base
.voltage
, clk
->temp
, -1);
202 if (ret
&& ret
!= -ENODEV
)
203 nvkm_error(subdev
, "failed to lower voltage: %d\n", ret
);
207 ret
= nvkm_therm_cstate(therm
, pstate
->fanspeed
, -1);
208 if (ret
&& ret
!= -ENODEV
)
209 nvkm_error(subdev
, "failed to lower fan speed: %d\n", ret
);
216 nvkm_cstate_del(struct nvkm_cstate
*cstate
)
218 list_del(&cstate
->head
);
223 nvkm_cstate_new(struct nvkm_clk
*clk
, int idx
, struct nvkm_pstate
*pstate
)
225 struct nvkm_bios
*bios
= clk
->subdev
.device
->bios
;
226 struct nvkm_volt
*volt
= clk
->subdev
.device
->volt
;
227 const struct nvkm_domain
*domain
= clk
->domains
;
228 struct nvkm_cstate
*cstate
= NULL
;
229 struct nvbios_cstepX cstepX
;
233 data
= nvbios_cstepXp(bios
, idx
, &ver
, &hdr
, &cstepX
);
237 if (volt
&& nvkm_volt_map_min(volt
, cstepX
.voltage
) > volt
->max_uv
)
240 cstate
= kzalloc(sizeof(*cstate
), GFP_KERNEL
);
244 *cstate
= pstate
->base
;
245 cstate
->voltage
= cstepX
.voltage
;
248 while (domain
&& domain
->name
!= nv_clk_src_max
) {
249 if (domain
->flags
& NVKM_CLK_DOM_FLAG_CORE
) {
250 u32 freq
= nvkm_clk_adjust(clk
, true, pstate
->pstate
,
251 domain
->bios
, cstepX
.freq
);
252 cstate
->domain
[domain
->name
] = freq
;
257 list_add(&cstate
->head
, &pstate
->list
);
261 /******************************************************************************
263 *****************************************************************************/
265 nvkm_pstate_prog(struct nvkm_clk
*clk
, int pstatei
)
267 struct nvkm_subdev
*subdev
= &clk
->subdev
;
268 struct nvkm_fb
*fb
= subdev
->device
->fb
;
269 struct nvkm_pci
*pci
= subdev
->device
->pci
;
270 struct nvkm_pstate
*pstate
;
273 list_for_each_entry(pstate
, &clk
->states
, head
) {
274 if (idx
++ == pstatei
)
278 nvkm_debug(subdev
, "setting performance state %d\n", pstatei
);
279 clk
->pstate
= pstatei
;
281 nvkm_pcie_set_link(pci
, pstate
->pcie_speed
, pstate
->pcie_width
);
283 if (fb
&& fb
->ram
&& fb
->ram
->func
->calc
) {
284 struct nvkm_ram
*ram
= fb
->ram
;
285 int khz
= pstate
->base
.domain
[nv_clk_src_mem
];
287 ret
= ram
->func
->calc(ram
, khz
);
289 ret
= ram
->func
->prog(ram
);
291 ram
->func
->tidy(ram
);
294 return nvkm_cstate_prog(clk
, pstate
, NVKM_CLK_CSTATE_HIGHEST
);
298 nvkm_pstate_work(struct work_struct
*work
)
300 struct nvkm_clk
*clk
= container_of(work
, typeof(*clk
), work
);
301 struct nvkm_subdev
*subdev
= &clk
->subdev
;
304 if (!atomic_xchg(&clk
->waiting
, 0))
306 clk
->pwrsrc
= power_supply_is_system_supplied();
308 nvkm_trace(subdev
, "P %d PWR %d U(AC) %d U(DC) %d A %d T %d°C D %d\n",
309 clk
->pstate
, clk
->pwrsrc
, clk
->ustate_ac
, clk
->ustate_dc
,
310 clk
->astate
, clk
->temp
, clk
->dstate
);
312 pstate
= clk
->pwrsrc
? clk
->ustate_ac
: clk
->ustate_dc
;
313 if (clk
->state_nr
&& pstate
!= -1) {
314 pstate
= (pstate
< 0) ? clk
->astate
: pstate
;
315 pstate
= min(pstate
, clk
->state_nr
- 1);
316 pstate
= max(pstate
, clk
->dstate
);
318 pstate
= clk
->pstate
= -1;
321 nvkm_trace(subdev
, "-> %d\n", pstate
);
322 if (pstate
!= clk
->pstate
) {
323 int ret
= nvkm_pstate_prog(clk
, pstate
);
325 nvkm_error(subdev
, "error setting pstate %d: %d\n",
330 wake_up_all(&clk
->wait
);
331 nvkm_notify_get(&clk
->pwrsrc_ntfy
);
335 nvkm_pstate_calc(struct nvkm_clk
*clk
, bool wait
)
337 atomic_set(&clk
->waiting
, 1);
338 schedule_work(&clk
->work
);
340 wait_event(clk
->wait
, !atomic_read(&clk
->waiting
));
345 nvkm_pstate_info(struct nvkm_clk
*clk
, struct nvkm_pstate
*pstate
)
347 const struct nvkm_domain
*clock
= clk
->domains
- 1;
348 struct nvkm_cstate
*cstate
;
349 struct nvkm_subdev
*subdev
= &clk
->subdev
;
350 char info
[3][32] = { "", "", "" };
354 if (pstate
->pstate
!= 0xff)
355 snprintf(name
, sizeof(name
), "%02x", pstate
->pstate
);
357 while ((++clock
)->name
!= nv_clk_src_max
) {
358 u32 lo
= pstate
->base
.domain
[clock
->name
];
363 nvkm_debug(subdev
, "%02x: %10d KHz\n", clock
->name
, lo
);
364 list_for_each_entry(cstate
, &pstate
->list
, head
) {
365 u32 freq
= cstate
->domain
[clock
->name
];
368 nvkm_debug(subdev
, "%10d KHz\n", freq
);
371 if (clock
->mname
&& ++i
< ARRAY_SIZE(info
)) {
375 snprintf(info
[i
], sizeof(info
[i
]), "%s %d MHz",
378 snprintf(info
[i
], sizeof(info
[i
]),
379 "%s %d-%d MHz", clock
->mname
, lo
, hi
);
384 nvkm_debug(subdev
, "%s: %s %s %s\n", name
, info
[0], info
[1], info
[2]);
388 nvkm_pstate_del(struct nvkm_pstate
*pstate
)
390 struct nvkm_cstate
*cstate
, *temp
;
392 list_for_each_entry_safe(cstate
, temp
, &pstate
->list
, head
) {
393 nvkm_cstate_del(cstate
);
396 list_del(&pstate
->head
);
401 nvkm_pstate_new(struct nvkm_clk
*clk
, int idx
)
403 struct nvkm_bios
*bios
= clk
->subdev
.device
->bios
;
404 const struct nvkm_domain
*domain
= clk
->domains
- 1;
405 struct nvkm_pstate
*pstate
;
406 struct nvkm_cstate
*cstate
;
407 struct nvbios_cstepE cstepE
;
408 struct nvbios_perfE perfE
;
409 u8 ver
, hdr
, cnt
, len
;
412 data
= nvbios_perfEp(bios
, idx
, &ver
, &hdr
, &cnt
, &len
, &perfE
);
415 if (perfE
.pstate
== 0xff)
418 pstate
= kzalloc(sizeof(*pstate
), GFP_KERNEL
);
419 cstate
= &pstate
->base
;
423 INIT_LIST_HEAD(&pstate
->list
);
425 pstate
->pstate
= perfE
.pstate
;
426 pstate
->fanspeed
= perfE
.fanspeed
;
427 pstate
->pcie_speed
= perfE
.pcie_speed
;
428 pstate
->pcie_width
= perfE
.pcie_width
;
429 cstate
->voltage
= perfE
.voltage
;
430 cstate
->domain
[nv_clk_src_core
] = perfE
.core
;
431 cstate
->domain
[nv_clk_src_shader
] = perfE
.shader
;
432 cstate
->domain
[nv_clk_src_mem
] = perfE
.memory
;
433 cstate
->domain
[nv_clk_src_vdec
] = perfE
.vdec
;
434 cstate
->domain
[nv_clk_src_dom6
] = perfE
.disp
;
436 while (ver
>= 0x40 && (++domain
)->name
!= nv_clk_src_max
) {
437 struct nvbios_perfS perfS
;
438 u8 sver
= ver
, shdr
= hdr
;
439 u32 perfSe
= nvbios_perfSp(bios
, data
, domain
->bios
,
440 &sver
, &shdr
, cnt
, len
, &perfS
);
441 if (perfSe
== 0 || sver
!= 0x40)
444 if (domain
->flags
& NVKM_CLK_DOM_FLAG_CORE
) {
445 perfS
.v40
.freq
= nvkm_clk_adjust(clk
, false,
451 cstate
->domain
[domain
->name
] = perfS
.v40
.freq
;
454 data
= nvbios_cstepEm(bios
, pstate
->pstate
, &ver
, &hdr
, &cstepE
);
456 int idx
= cstepE
.index
;
458 nvkm_cstate_new(clk
, idx
, pstate
);
462 nvkm_pstate_info(clk
, pstate
);
463 list_add_tail(&pstate
->head
, &clk
->states
);
468 /******************************************************************************
469 * Adjustment triggers
470 *****************************************************************************/
472 nvkm_clk_ustate_update(struct nvkm_clk
*clk
, int req
)
474 struct nvkm_pstate
*pstate
;
477 if (!clk
->allow_reclock
)
480 if (req
!= -1 && req
!= -2) {
481 list_for_each_entry(pstate
, &clk
->states
, head
) {
482 if (pstate
->pstate
== req
)
487 if (pstate
->pstate
!= req
)
496 nvkm_clk_nstate(struct nvkm_clk
*clk
, const char *mode
, int arglen
)
500 if (clk
->allow_reclock
&& !strncasecmpz(mode
, "auto", arglen
))
503 if (strncasecmpz(mode
, "disabled", arglen
)) {
504 char save
= mode
[arglen
];
507 ((char *)mode
)[arglen
] = '\0';
508 if (!kstrtol(mode
, 0, &v
)) {
509 ret
= nvkm_clk_ustate_update(clk
, v
);
513 ((char *)mode
)[arglen
] = save
;
520 nvkm_clk_ustate(struct nvkm_clk
*clk
, int req
, int pwr
)
522 int ret
= nvkm_clk_ustate_update(clk
, req
);
524 if (ret
-= 2, pwr
) clk
->ustate_ac
= ret
;
525 else clk
->ustate_dc
= ret
;
526 return nvkm_pstate_calc(clk
, true);
532 nvkm_clk_astate(struct nvkm_clk
*clk
, int req
, int rel
, bool wait
)
534 if (!rel
) clk
->astate
= req
;
535 if ( rel
) clk
->astate
+= rel
;
536 clk
->astate
= min(clk
->astate
, clk
->state_nr
- 1);
537 clk
->astate
= max(clk
->astate
, 0);
538 return nvkm_pstate_calc(clk
, wait
);
542 nvkm_clk_tstate(struct nvkm_clk
*clk
, u8 temp
)
544 if (clk
->temp
== temp
)
547 return nvkm_pstate_calc(clk
, false);
551 nvkm_clk_dstate(struct nvkm_clk
*clk
, int req
, int rel
)
553 if (!rel
) clk
->dstate
= req
;
554 if ( rel
) clk
->dstate
+= rel
;
555 clk
->dstate
= min(clk
->dstate
, clk
->state_nr
- 1);
556 clk
->dstate
= max(clk
->dstate
, 0);
557 return nvkm_pstate_calc(clk
, true);
561 nvkm_clk_pwrsrc(struct nvkm_notify
*notify
)
563 struct nvkm_clk
*clk
=
564 container_of(notify
, typeof(*clk
), pwrsrc_ntfy
);
565 nvkm_pstate_calc(clk
, false);
566 return NVKM_NOTIFY_DROP
;
569 /******************************************************************************
570 * subdev base class implementation
571 *****************************************************************************/
574 nvkm_clk_read(struct nvkm_clk
*clk
, enum nv_clk_src src
)
576 return clk
->func
->read(clk
, src
);
580 nvkm_clk_fini(struct nvkm_subdev
*subdev
, bool suspend
)
582 struct nvkm_clk
*clk
= nvkm_clk(subdev
);
583 nvkm_notify_put(&clk
->pwrsrc_ntfy
);
584 flush_work(&clk
->work
);
586 clk
->func
->fini(clk
);
591 nvkm_clk_init(struct nvkm_subdev
*subdev
)
593 struct nvkm_clk
*clk
= nvkm_clk(subdev
);
594 const struct nvkm_domain
*clock
= clk
->domains
;
597 memset(&clk
->bstate
, 0x00, sizeof(clk
->bstate
));
598 INIT_LIST_HEAD(&clk
->bstate
.list
);
599 clk
->bstate
.pstate
= 0xff;
601 while (clock
->name
!= nv_clk_src_max
) {
602 ret
= nvkm_clk_read(clk
, clock
->name
);
604 nvkm_error(subdev
, "%02x freq unknown\n", clock
->name
);
607 clk
->bstate
.base
.domain
[clock
->name
] = ret
;
611 nvkm_pstate_info(clk
, &clk
->bstate
);
614 return clk
->func
->init(clk
);
616 clk
->astate
= clk
->state_nr
- 1;
619 clk
->temp
= 90; /* reasonable default value */
620 nvkm_pstate_calc(clk
, true);
625 nvkm_clk_dtor(struct nvkm_subdev
*subdev
)
627 struct nvkm_clk
*clk
= nvkm_clk(subdev
);
628 struct nvkm_pstate
*pstate
, *temp
;
630 nvkm_notify_fini(&clk
->pwrsrc_ntfy
);
632 /* Early return if the pstates have been provided statically */
633 if (clk
->func
->pstates
)
636 list_for_each_entry_safe(pstate
, temp
, &clk
->states
, head
) {
637 nvkm_pstate_del(pstate
);
643 static const struct nvkm_subdev_func
645 .dtor
= nvkm_clk_dtor
,
646 .init
= nvkm_clk_init
,
647 .fini
= nvkm_clk_fini
,
651 nvkm_clk_ctor(const struct nvkm_clk_func
*func
, struct nvkm_device
*device
,
652 int index
, bool allow_reclock
, struct nvkm_clk
*clk
)
654 struct nvkm_subdev
*subdev
= &clk
->subdev
;
655 struct nvkm_bios
*bios
= device
->bios
;
656 int ret
, idx
, arglen
;
658 struct nvbios_vpstate_header h
;
660 nvkm_subdev_ctor(&nvkm_clk
, device
, index
, subdev
);
662 if (bios
&& !nvbios_vpstate_parse(bios
, &h
)) {
663 struct nvbios_vpstate_entry base
, boost
;
664 if (!nvbios_vpstate_entry(bios
, &h
, h
.boost_id
, &boost
))
665 clk
->boost_khz
= boost
.clock_mhz
* 1000;
666 if (!nvbios_vpstate_entry(bios
, &h
, h
.base_id
, &base
))
667 clk
->base_khz
= base
.clock_mhz
* 1000;
671 INIT_LIST_HEAD(&clk
->states
);
672 clk
->domains
= func
->domains
;
675 clk
->allow_reclock
= allow_reclock
;
677 INIT_WORK(&clk
->work
, nvkm_pstate_work
);
678 init_waitqueue_head(&clk
->wait
);
679 atomic_set(&clk
->waiting
, 0);
681 /* If no pstates are provided, try and fetch them from the BIOS */
682 if (!func
->pstates
) {
685 ret
= nvkm_pstate_new(clk
, idx
++);
688 for (idx
= 0; idx
< func
->nr_pstates
; idx
++)
689 list_add_tail(&func
->pstates
[idx
].head
, &clk
->states
);
690 clk
->state_nr
= func
->nr_pstates
;
693 ret
= nvkm_notify_init(NULL
, &device
->event
, nvkm_clk_pwrsrc
, true,
694 NULL
, 0, 0, &clk
->pwrsrc_ntfy
);
698 mode
= nvkm_stropt(device
->cfgopt
, "NvClkMode", &arglen
);
700 clk
->ustate_ac
= nvkm_clk_nstate(clk
, mode
, arglen
);
701 clk
->ustate_dc
= nvkm_clk_nstate(clk
, mode
, arglen
);
704 mode
= nvkm_stropt(device
->cfgopt
, "NvClkModeAC", &arglen
);
706 clk
->ustate_ac
= nvkm_clk_nstate(clk
, mode
, arglen
);
708 mode
= nvkm_stropt(device
->cfgopt
, "NvClkModeDC", &arglen
);
710 clk
->ustate_dc
= nvkm_clk_nstate(clk
, mode
, arglen
);
712 clk
->boost_mode
= nvkm_longopt(device
->cfgopt
, "NvBoost",
713 NVKM_CLK_BOOST_NONE
);
718 nvkm_clk_new_(const struct nvkm_clk_func
*func
, struct nvkm_device
*device
,
719 int index
, bool allow_reclock
, struct nvkm_clk
**pclk
)
721 if (!(*pclk
= kzalloc(sizeof(**pclk
), GFP_KERNEL
)))
723 return nvkm_clk_ctor(func
, device
, index
, allow_reclock
, *pclk
);