diff options
author | Vaikundanathan S <vaikuns@nvidia.com> | 2018-04-23 07:51:58 -0400 |
---|---|---|
committer | Tejal Kudav <tkudav@nvidia.com> | 2018-06-14 09:44:06 -0400 |
commit | 054546525571dde1117376176f00511f13168f07 (patch) | |
tree | 477c3ef6d9502ce584f2588e0240a8fbd93be2a5 /drivers/gpu/nvgpu/clk | |
parent | 14d8430697d6867325fc1f40eef820cca40c3d2f (diff) |
gpu: nvgpu: set gv10x boot clock
- Set gv10x boot gpcclk to 952 MHz
- Created ops to set gv10x boot gpcclk instead
of using clk arbiter to set clocks
Bug 200399373
Change-Id: Ice5956f79d4a52abf455506a798cf7b914f3d3ed
Signed-off-by: Vaikundanathan S <vaikuns@nvidia.com>
Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1700788
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/clk')
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk.c | 151 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk.h | 10 |
2 files changed, 161 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk.c b/drivers/gpu/nvgpu/clk/clk.c index 28f08cb6..5d6ae19d 100644 --- a/drivers/gpu/nvgpu/clk/clk.c +++ b/drivers/gpu/nvgpu/clk/clk.c | |||
@@ -182,6 +182,7 @@ u32 clk_pmu_vin_load(struct gk20a *g) | |||
182 | (u32)sizeof(struct pmu_hdr); | 182 | (u32)sizeof(struct pmu_hdr); |
183 | 183 | ||
184 | cmd.cmd.clk.cmd_type = NV_PMU_CLK_CMD_ID_RPC; | 184 | cmd.cmd.clk.cmd_type = NV_PMU_CLK_CMD_ID_RPC; |
185 | cmd.cmd.clk.generic.b_perf_daemon_cmd =false; | ||
185 | 186 | ||
186 | payload.in.buf = (u8 *)&rpccall; | 187 | payload.in.buf = (u8 *)&rpccall; |
187 | payload.in.size = (u32)sizeof(struct nv_pmu_clk_rpc); | 188 | payload.in.size = (u32)sizeof(struct nv_pmu_clk_rpc); |
@@ -547,6 +548,156 @@ u32 clk_domain_print_vf_table(struct gk20a *g, u32 clkapidomain) | |||
547 | return status; | 548 | return status; |
548 | } | 549 | } |
549 | 550 | ||
551 | static int clk_program_fllclks(struct gk20a *g, struct change_fll_clk *fllclk) | ||
552 | { | ||
553 | int status = -EINVAL; | ||
554 | struct clk_domain *pdomain; | ||
555 | u8 i; | ||
556 | struct clk_pmupstate *pclk = &g->clk_pmu; | ||
557 | u16 clkmhz = 0; | ||
558 | struct clk_domain_3x_master *p3xmaster; | ||
559 | struct clk_domain_3x_slave *p3xslave; | ||
560 | unsigned long slaveidxmask; | ||
561 | struct set_fll_clk setfllclk; | ||
562 | |||
563 | if (fllclk->api_clk_domain != CTRL_CLK_DOMAIN_GPCCLK) | ||
564 | return -EINVAL; | ||
565 | if (fllclk->voltuv == 0) | ||
566 | return -EINVAL; | ||
567 | if (fllclk->clkmhz == 0) | ||
568 | return -EINVAL; | ||
569 | |||
570 | setfllclk.voltuv = fllclk->voltuv; | ||
571 | setfllclk.gpc2clkmhz = fllclk->clkmhz; | ||
572 | |||
573 | BOARDOBJGRP_FOR_EACH(&(pclk->clk_domainobjs.super.super), | ||
574 | struct clk_domain *, pdomain, i) { | ||
575 | |||
576 | if (pdomain->api_domain == fllclk->api_clk_domain) { | ||
577 | |||
578 | if (!pdomain->super.implements(g, &pdomain->super, | ||
579 | CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER)) { | ||
580 | status = -EINVAL; | ||
581 | goto done; | ||
582 | } | ||
583 | p3xmaster = (struct clk_domain_3x_master *)pdomain; | ||
584 | slaveidxmask = p3xmaster->slave_idxs_mask; | ||
585 | for_each_set_bit(i, &slaveidxmask, 32) { | ||
586 | p3xslave = (struct clk_domain_3x_slave *) | ||
587 | CLK_CLK_DOMAIN_GET(pclk, i); | ||
588 | if ((p3xslave->super.super.super.api_domain != | ||
589 | CTRL_CLK_DOMAIN_XBARCLK) && | ||
590 | (p3xslave->super.super.super.api_domain != | ||
591 | CTRL_CLK_DOMAIN_SYSCLK)) | ||
592 | continue; | ||
593 | clkmhz = 0; | ||
594 | status = p3xslave->clkdomainclkgetslaveclk(g, | ||
595 | pclk, | ||
596 | (struct clk_domain *)p3xslave, | ||
597 | &clkmhz, | ||
598 | fllclk->clkmhz); | ||
599 | if (status) { | ||
600 | status = -EINVAL; | ||
601 | goto done; | ||
602 | } | ||
603 | if (p3xslave->super.super.super.api_domain == | ||
604 | CTRL_CLK_DOMAIN_XBARCLK) | ||
605 | setfllclk.xbar2clkmhz = clkmhz; | ||
606 | if (p3xslave->super.super.super.api_domain == | ||
607 | CTRL_CLK_DOMAIN_SYSCLK) | ||
608 | setfllclk.sys2clkmhz = clkmhz; | ||
609 | } | ||
610 | } | ||
611 | } | ||
612 | /*set regime ids */ | ||
613 | status = get_regime_id(g, CTRL_CLK_DOMAIN_GPCCLK, | ||
614 | &setfllclk.current_regime_id_gpc); | ||
615 | if (status) | ||
616 | goto done; | ||
617 | |||
618 | setfllclk.target_regime_id_gpc = find_regime_id(g, | ||
619 | CTRL_CLK_DOMAIN_GPCCLK, setfllclk.gpc2clkmhz); | ||
620 | |||
621 | status = get_regime_id(g, CTRL_CLK_DOMAIN_SYSCLK, | ||
622 | &setfllclk.current_regime_id_sys); | ||
623 | if (status) | ||
624 | goto done; | ||
625 | |||
626 | setfllclk.target_regime_id_sys = find_regime_id(g, | ||
627 | CTRL_CLK_DOMAIN_SYSCLK, setfllclk.sys2clkmhz); | ||
628 | |||
629 | status = get_regime_id(g, CTRL_CLK_DOMAIN_XBARCLK, | ||
630 | &setfllclk.current_regime_id_xbar); | ||
631 | if (status) | ||
632 | goto done; | ||
633 | |||
634 | setfllclk.target_regime_id_xbar = find_regime_id(g, | ||
635 | CTRL_CLK_DOMAIN_XBARCLK, setfllclk.xbar2clkmhz); | ||
636 | |||
637 | status = clk_pmu_vf_inject(g, &setfllclk); | ||
638 | |||
639 | if (status) | ||
640 | nvgpu_err(g, | ||
641 | "vf inject to change clk failed"); | ||
642 | |||
643 | /* save regime ids */ | ||
644 | status = set_regime_id(g, CTRL_CLK_DOMAIN_XBARCLK, | ||
645 | setfllclk.target_regime_id_xbar); | ||
646 | if (status) | ||
647 | goto done; | ||
648 | |||
649 | status = set_regime_id(g, CTRL_CLK_DOMAIN_GPCCLK, | ||
650 | setfllclk.target_regime_id_gpc); | ||
651 | if (status) | ||
652 | goto done; | ||
653 | |||
654 | status = set_regime_id(g, CTRL_CLK_DOMAIN_SYSCLK, | ||
655 | setfllclk.target_regime_id_sys); | ||
656 | if (status) | ||
657 | goto done; | ||
658 | done: | ||
659 | return status; | ||
660 | } | ||
661 | |||
662 | u32 nvgpu_clk_set_boot_fll_clk_gv10x(struct gk20a *g) | ||
663 | { | ||
664 | int status; | ||
665 | struct change_fll_clk bootfllclk; | ||
666 | u16 gpcclk_clkmhz = BOOT_GPCCLK_MHZ; | ||
667 | u32 gpcclk_voltuv = 0; | ||
668 | u32 voltuv = 0; | ||
669 | |||
670 | status = clk_vf_point_cache(g); | ||
671 | if (status) { | ||
672 | nvgpu_err(g,"caching failed"); | ||
673 | return status; | ||
674 | } | ||
675 | |||
676 | status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_GPCCLK, | ||
677 | &gpcclk_clkmhz, &gpcclk_voltuv, CTRL_VOLT_DOMAIN_LOGIC); | ||
678 | if (status) { | ||
679 | nvgpu_err(g,"failed 1"); | ||
680 | return status; | ||
681 | } | ||
682 | |||
683 | voltuv = gpcclk_voltuv; | ||
684 | |||
685 | status = volt_set_voltage(g, voltuv, 0); | ||
686 | if (status) | ||
687 | nvgpu_err(g, | ||
688 | "attempt to set boot voltage failed %d", | ||
689 | voltuv); | ||
690 | |||
691 | bootfllclk.api_clk_domain = CTRL_CLK_DOMAIN_GPCCLK; | ||
692 | bootfllclk.clkmhz = gpcclk_clkmhz; | ||
693 | bootfllclk.voltuv = voltuv; | ||
694 | status = clk_program_fllclks(g, &bootfllclk); | ||
695 | if (status) | ||
696 | nvgpu_err(g, "attempt to set boot gpcclk failed"); | ||
697 | |||
698 | return status; | ||
699 | } | ||
700 | |||
550 | u32 clk_domain_get_f_or_v( | 701 | u32 clk_domain_get_f_or_v( |
551 | struct gk20a *g, | 702 | struct gk20a *g, |
552 | u32 clkapidomain, | 703 | u32 clkapidomain, |
diff --git a/drivers/gpu/nvgpu/clk/clk.h b/drivers/gpu/nvgpu/clk/clk.h index 019a1c11..70b04fc4 100644 --- a/drivers/gpu/nvgpu/clk/clk.h +++ b/drivers/gpu/nvgpu/clk/clk.h | |||
@@ -35,9 +35,12 @@ | |||
35 | #define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_SKIP 0x10 | 35 | #define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_SKIP 0x10 |
36 | #define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_MASK 0x1F | 36 | #define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_MASK 0x1F |
37 | #define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_SHIFT 0 | 37 | #define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_SHIFT 0 |
38 | #define BOOT_GPCCLK_MHZ 952 | ||
38 | 39 | ||
39 | struct gk20a; | 40 | struct gk20a; |
40 | 41 | ||
42 | int clk_set_boot_fll_clk(struct gk20a *g); | ||
43 | |||
41 | /* clock related defines for GPUs supporting clock control from pmu*/ | 44 | /* clock related defines for GPUs supporting clock control from pmu*/ |
42 | struct clk_pmupstate { | 45 | struct clk_pmupstate { |
43 | struct avfsvinobjs avfs_vinobjs; | 46 | struct avfsvinobjs avfs_vinobjs; |
@@ -56,6 +59,12 @@ struct clockentry { | |||
56 | u32 api_clk_domain; | 59 | u32 api_clk_domain; |
57 | }; | 60 | }; |
58 | 61 | ||
62 | struct change_fll_clk { | ||
63 | u32 api_clk_domain; | ||
64 | u16 clkmhz; | ||
65 | u32 voltuv; | ||
66 | }; | ||
67 | |||
59 | struct set_fll_clk { | 68 | struct set_fll_clk { |
60 | u32 voltuv; | 69 | u32 voltuv; |
61 | u16 gpc2clkmhz; | 70 | u16 gpc2clkmhz; |
@@ -133,4 +142,5 @@ u32 nvgpu_clk_vf_change_inject_data_fill_gv10x(struct gk20a *g, | |||
133 | u32 nvgpu_clk_vf_change_inject_data_fill_gp10x(struct gk20a *g, | 142 | u32 nvgpu_clk_vf_change_inject_data_fill_gp10x(struct gk20a *g, |
134 | struct nv_pmu_clk_rpc *rpccall, | 143 | struct nv_pmu_clk_rpc *rpccall, |
135 | struct set_fll_clk *setfllclk); | 144 | struct set_fll_clk *setfllclk); |
145 | u32 nvgpu_clk_set_boot_fll_clk_gv10x(struct gk20a *g); | ||
136 | #endif | 146 | #endif |