summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/clk/clk_domain.c
diff options
context:
space:
mode:
authorVijayakumar <vsubbu@nvidia.com>2016-08-31 08:10:24 -0400
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:56:50 -0500
commit1b1090512020369df18dbe36336ac5a85d2cd693 (patch)
tree41f3a11dbdff21815545e0e69734c60416783e5e /drivers/gpu/nvgpu/clk/clk_domain.c
parente28ef73ec9baea7df631606298f8c210dc8f31a8 (diff)
gpu: nvgpu: support to parse VF table
JIRA DNVGPU-123 function was added to retrieve V for F or F for V for a given clock domain. Clock domain can be master or slave. F or V can be intermediate point between two successive V or F values in VF table. VF table should be cached before calling this function. A F value below Fmin will return Vmin. F > Fmax will return error A V value above Vmax wil return F max. A V value below Vmin will return error. Change-Id: I28b4e8647510c6933e9e1204cfff31d74616e11a Signed-off-by: Vijayakumar <vsubbu@nvidia.com> Reviewed-on: http://git-master/r/1211234 (cherry-picked from commit 5b83b03f2454fbec8d49a064ed09b09c92d3e9fa) Reviewed-on: http://git-master/r/1235054 Reviewed-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/clk/clk_domain.c')
-rw-r--r--drivers/gpu/nvgpu/clk/clk_domain.c125
1 files changed, 122 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_domain.c b/drivers/gpu/nvgpu/clk/clk_domain.c
index 7371946c..c8da851a 100644
--- a/drivers/gpu/nvgpu/clk/clk_domain.c
+++ b/drivers/gpu/nvgpu/clk/clk_domain.c
@@ -136,6 +136,8 @@ u32 clk_domain_sw_setup(struct gk20a *g)
136 struct boardobjgrp *pboardobjgrp = NULL; 136 struct boardobjgrp *pboardobjgrp = NULL;
137 struct clk_domains *pclkdomainobjs; 137 struct clk_domains *pclkdomainobjs;
138 struct clk_domain *pdomain; 138 struct clk_domain *pdomain;
139 struct clk_domain_3x_master *pdomain_master;
140 struct clk_domain_3x_slave *pdomain_slave;
139 u8 i; 141 u8 i;
140 142
141 gk20a_dbg_info(""); 143 gk20a_dbg_info("");
@@ -186,6 +188,7 @@ u32 clk_domain_sw_setup(struct gk20a *g)
186 188
187 BOARDOBJGRP_FOR_EACH(&(pclkdomainobjs->super.super), 189 BOARDOBJGRP_FOR_EACH(&(pclkdomainobjs->super.super),
188 struct clk_domain *, pdomain, i) { 190 struct clk_domain *, pdomain, i) {
191 pdomain_master = NULL;
189 if (pdomain->super.implements(g, &pdomain->super, 192 if (pdomain->super.implements(g, &pdomain->super,
190 CTRL_CLK_CLK_DOMAIN_TYPE_3X_PROG)) { 193 CTRL_CLK_CLK_DOMAIN_TYPE_3X_PROG)) {
191 status = boardobjgrpmask_bitset( 194 status = boardobjgrpmask_bitset(
@@ -201,6 +204,18 @@ u32 clk_domain_sw_setup(struct gk20a *g)
201 if (status) 204 if (status)
202 goto done; 205 goto done;
203 } 206 }
207
208 if (pdomain->super.implements(g, &pdomain->super,
209 CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE)) {
210 pdomain_slave =
211 (struct clk_domain_3x_slave *)pdomain;
212 pdomain_master =
213 (struct clk_domain_3x_master *)
214 (CLK_CLK_DOMAIN_GET((&g->clk_pmu),
215 pdomain_slave->master_idx));
216 pdomain_master->slave_idxs_mask |= BIT(i);
217 }
218
204 } 219 }
205 220
206done: 221done:
@@ -407,6 +422,20 @@ static u32 clkdomainclkproglink_not_supported(struct gk20a *g,
407 return -EINVAL; 422 return -EINVAL;
408} 423}
409 424
425static u32 clkdomainvfsearch_stub(
426 struct gk20a *g,
427 struct clk_pmupstate *pclk,
428 struct clk_domain *pdomain,
429 u16 *clkmhz,
430 u32 *voltuv,
431 u8 rail
432)
433{
434 gk20a_dbg_info("");
435 return -EINVAL;
436}
437
438
410static u32 clk_domain_construct_super(struct gk20a *g, 439static u32 clk_domain_construct_super(struct gk20a *g,
411 struct boardobj **ppboardobj, 440 struct boardobj **ppboardobj,
412 u16 size, void *pargs) 441 u16 size, void *pargs)
@@ -429,6 +458,9 @@ static u32 clk_domain_construct_super(struct gk20a *g,
429 pdomain->clkdomainclkproglink = 458 pdomain->clkdomainclkproglink =
430 clkdomainclkproglink_not_supported; 459 clkdomainclkproglink_not_supported;
431 460
461 pdomain->clkdomainclkvfsearch =
462 clkdomainvfsearch_stub;
463
432 pdomain->api_domain = ptmpdomain->api_domain; 464 pdomain->api_domain = ptmpdomain->api_domain;
433 pdomain->domain = ptmpdomain->domain; 465 pdomain->domain = ptmpdomain->domain;
434 pdomain->perf_domain_grp_idx = 466 pdomain->perf_domain_grp_idx =
@@ -508,6 +540,92 @@ static u32 clkdomainclkproglink_3x_prog(struct gk20a *g,
508 return status; 540 return status;
509} 541}
510 542
543static u32 clkdomainvfsearch
544(
545 struct gk20a *g,
546 struct clk_pmupstate *pclk,
547 struct clk_domain *pdomain,
548 u16 *pclkmhz,
549 u32 *pvoltuv,
550 u8 rail
551)
552{
553 u32 status = 0;
554 struct clk_domain_3x_master *p3xmaster =
555 (struct clk_domain_3x_master *)pdomain;
556 struct clk_prog *pprog = NULL;
557 struct clk_prog_1x_master *pprog1xmaster = NULL;
558 u8 i;
559 u8 *pslaveidx = NULL;
560 u8 slaveidx;
561 u16 clkmhz;
562 u32 voltuv;
563 u16 bestclkmhz;
564 u32 bestvoltuv;
565
566 gk20a_dbg_info("");
567 if ((*pclkmhz != 0) && (*pvoltuv != 0))
568 return -EINVAL;
569
570 bestclkmhz = *pclkmhz;
571 bestvoltuv = *pvoltuv;
572
573 if (pdomain->super.implements(g, &pdomain->super,
574 CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE)) {
575 slaveidx = BOARDOBJ_GET_IDX(pdomain);
576 pslaveidx = &slaveidx;
577 p3xmaster = (struct clk_domain_3x_master *)
578 CLK_CLK_DOMAIN_GET(pclk,
579 ((struct clk_domain_3x_slave *)
580 pdomain)->master_idx);
581 }
582
583 /* Iterate over the set of CLK_PROGs pointed at by this domain.*/
584 for (i = p3xmaster->super.clk_prog_idx_first;
585 i <= p3xmaster->super.clk_prog_idx_last;
586 i++) {
587 clkmhz = *pclkmhz;
588 voltuv = *pvoltuv;
589 pprog = CLK_CLK_PROG_GET(pclk, i);
590
591 /* MASTER CLK_DOMAINs must point to MASTER CLK_PROGs.*/
592 if (!pprog->super.implements(g, &pprog->super,
593 CTRL_CLK_CLK_PROG_TYPE_1X_MASTER)) {
594 status = -EINVAL;
595 goto done;
596 }
597
598 pprog1xmaster = (struct clk_prog_1x_master *)pprog;
599 status = pprog1xmaster->vflookup(g, pclk, pprog1xmaster,
600 pslaveidx, &clkmhz, &voltuv, rail);
601 /* if look up has found the V or F value matching to other
602 exit */
603 if (status == 0) {
604 if (*pclkmhz == 0) {
605 bestclkmhz = clkmhz;
606 } else {
607 bestvoltuv = voltuv;
608 break;
609 }
610 }
611 }
612 /* clk and volt sent as zero to pring vf table */
613 if ((*pclkmhz == 0) && (*pvoltuv == 0)) {
614 status = 0;
615 goto done;
616 }
617 /* atleast one search found a matching value? */
618 if ((bestvoltuv != 0) && (bestclkmhz != 0)) {
619 *pclkmhz = bestclkmhz;
620 *pvoltuv = bestvoltuv;
621 status = 0;
622 goto done;
623 }
624done:
625 gk20a_dbg_info("done status %x", status);
626 return status;
627}
628
511static u32 _clk_domain_pmudatainit_3x_prog(struct gk20a *g, 629static u32 _clk_domain_pmudatainit_3x_prog(struct gk20a *g,
512 struct boardobj *board_obj_ptr, 630 struct boardobj *board_obj_ptr,
513 struct nv_pmu_boardobj *ppmudata) 631 struct nv_pmu_boardobj *ppmudata)
@@ -568,6 +686,9 @@ static u32 clk_domain_construct_3x_prog(struct gk20a *g,
568 pdomain->super.super.clkdomainclkproglink = 686 pdomain->super.super.clkdomainclkproglink =
569 clkdomainclkproglink_3x_prog; 687 clkdomainclkproglink_3x_prog;
570 688
689 pdomain->super.super.clkdomainclkvfsearch =
690 clkdomainvfsearch;
691
571 pdomain->clk_prog_idx_first = ptmpdomain->clk_prog_idx_first; 692 pdomain->clk_prog_idx_first = ptmpdomain->clk_prog_idx_first;
572 pdomain->clk_prog_idx_last = ptmpdomain->clk_prog_idx_last; 693 pdomain->clk_prog_idx_last = ptmpdomain->clk_prog_idx_last;
573 pdomain->noise_unaware_ordering_index = 694 pdomain->noise_unaware_ordering_index =
@@ -707,8 +828,6 @@ static u32 clk_domain_construct_3x_master(struct gk20a *g,
707{ 828{
708 struct boardobj *ptmpobj = (struct boardobj *)pargs; 829 struct boardobj *ptmpobj = (struct boardobj *)pargs;
709 struct clk_domain_3x_master *pdomain; 830 struct clk_domain_3x_master *pdomain;
710 struct clk_domain_3x_master *ptmpdomain =
711 (struct clk_domain_3x_master *)pargs;
712 u32 status = 0; 831 u32 status = 0;
713 832
714 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER) 833 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER)
@@ -726,7 +845,7 @@ static u32 clk_domain_construct_3x_master(struct gk20a *g,
726 pdomain->super.super.super.clkdomainclkproglink = 845 pdomain->super.super.super.clkdomainclkproglink =
727 clkdomainclkproglink_3x_master; 846 clkdomainclkproglink_3x_master;
728 847
729 pdomain->slave_idxs_mask = ptmpdomain->slave_idxs_mask; 848 pdomain->slave_idxs_mask = 0;
730 849
731 return status; 850 return status;
732} 851}