diff options
author | Vijayakumar <vsubbu@nvidia.com> | 2016-09-12 13:06:33 -0400 |
---|---|---|
committer | Deepak Nibade <dnibade@nvidia.com> | 2016-12-27 04:56:50 -0500 |
commit | 3c351f5bb2d04c1f70c72f3f2fd758bbb340877c (patch) | |
tree | cdaaf5547d6a2663111ba3dadb60d723f5833683 /drivers/gpu/nvgpu/clk | |
parent | 1b1090512020369df18dbe36336ac5a85d2cd693 (diff) |
gpu: nvgpu: add function to retrieve clk points
JIRA DNVGPU-123
Function will copy possible clock points for
a given master clock domain to pointer passed.
pointer with NULL value and count of zero can be passed
to query number of clock points for a given domain so that
memory can be allocated and function called again to
fill clock points
Change-Id: Iec6206f23789980036be99793599e934bd221035
Reviewed-on: http://git-master/r/1218912
(cherry picked from commit 9219697bff1e12deb605325055a02a7b387996e9)
Signed-off-by: Vijayakumar <vsubbu@nvidia.com>
Reviewed-on: http://git-master/r/1235055
Reviewed-by: Thomas Fleury <tfleury@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/clk')
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk.c | 31 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk.h | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_domain.c | 83 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_domain.h | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_prog.c | 61 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_prog.h | 7 |
6 files changed, 194 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk.c b/drivers/gpu/nvgpu/clk/clk.c index 34b344c8..7ee4f283 100644 --- a/drivers/gpu/nvgpu/clk/clk.c +++ b/drivers/gpu/nvgpu/clk/clk.c | |||
@@ -236,3 +236,34 @@ u32 clk_domain_get_f_or_v( | |||
236 | } | 236 | } |
237 | return status; | 237 | return status; |
238 | } | 238 | } |
239 | |||
240 | u32 clk_domain_get_f_points( | ||
241 | struct gk20a *g, | ||
242 | u32 clkapidomain, | ||
243 | u32 *pfpointscount, | ||
244 | u16 *pfreqpointsinmhz | ||
245 | ) | ||
246 | { | ||
247 | u32 status = -EINVAL; | ||
248 | struct clk_domain *pdomain; | ||
249 | u8 i; | ||
250 | struct clk_pmupstate *pclk = &g->clk_pmu; | ||
251 | |||
252 | if (pfpointscount == NULL) | ||
253 | return -EINVAL; | ||
254 | |||
255 | if ((pfreqpointsinmhz == NULL) && (*pfpointscount != 0)) | ||
256 | return -EINVAL; | ||
257 | |||
258 | BOARDOBJGRP_FOR_EACH(&(pclk->clk_domainobjs.super.super), | ||
259 | struct clk_domain *, pdomain, i) { | ||
260 | if (pdomain->api_domain == clkapidomain) { | ||
261 | status = pdomain->clkdomainclkgetfpoints(g, pclk, | ||
262 | pdomain, pfpointscount, | ||
263 | pfreqpointsinmhz, | ||
264 | CLK_PROG_VFE_ENTRY_LOGIC); | ||
265 | return status; | ||
266 | } | ||
267 | } | ||
268 | return status; | ||
269 | } | ||
diff --git a/drivers/gpu/nvgpu/clk/clk.h b/drivers/gpu/nvgpu/clk/clk.h index 0d12ba7d..1f25fa4e 100644 --- a/drivers/gpu/nvgpu/clk/clk.h +++ b/drivers/gpu/nvgpu/clk/clk.h | |||
@@ -92,5 +92,11 @@ u32 clk_domain_get_f_or_v | |||
92 | u16 *pclkmhz, | 92 | u16 *pclkmhz, |
93 | u32 *pvoltuv | 93 | u32 *pvoltuv |
94 | ); | 94 | ); |
95 | u32 clk_domain_get_f_points( | ||
96 | struct gk20a *g, | ||
97 | u32 clkapidomain, | ||
98 | u32 *fpointscount, | ||
99 | u16 *freqpointsinmhz | ||
100 | ); | ||
95 | 101 | ||
96 | #endif | 102 | #endif |
diff --git a/drivers/gpu/nvgpu/clk/clk_domain.c b/drivers/gpu/nvgpu/clk/clk_domain.c index c8da851a..f87530dc 100644 --- a/drivers/gpu/nvgpu/clk/clk_domain.c +++ b/drivers/gpu/nvgpu/clk/clk_domain.c | |||
@@ -435,6 +435,19 @@ static u32 clkdomainvfsearch_stub( | |||
435 | return -EINVAL; | 435 | return -EINVAL; |
436 | } | 436 | } |
437 | 437 | ||
438 | static u32 clkdomaingetfpoints_stub( | ||
439 | struct gk20a *g, | ||
440 | struct clk_pmupstate *pclk, | ||
441 | struct clk_domain *pdomain, | ||
442 | u32 *pfpointscount, | ||
443 | u16 *pfreqpointsinmhz, | ||
444 | u8 rail | ||
445 | ) | ||
446 | { | ||
447 | gk20a_dbg_info(""); | ||
448 | return -EINVAL; | ||
449 | } | ||
450 | |||
438 | 451 | ||
439 | static u32 clk_domain_construct_super(struct gk20a *g, | 452 | static u32 clk_domain_construct_super(struct gk20a *g, |
440 | struct boardobj **ppboardobj, | 453 | struct boardobj **ppboardobj, |
@@ -461,6 +474,9 @@ static u32 clk_domain_construct_super(struct gk20a *g, | |||
461 | pdomain->clkdomainclkvfsearch = | 474 | pdomain->clkdomainclkvfsearch = |
462 | clkdomainvfsearch_stub; | 475 | clkdomainvfsearch_stub; |
463 | 476 | ||
477 | pdomain->clkdomainclkgetfpoints = | ||
478 | clkdomaingetfpoints_stub; | ||
479 | |||
464 | pdomain->api_domain = ptmpdomain->api_domain; | 480 | pdomain->api_domain = ptmpdomain->api_domain; |
465 | pdomain->domain = ptmpdomain->domain; | 481 | pdomain->domain = ptmpdomain->domain; |
466 | pdomain->perf_domain_grp_idx = | 482 | pdomain->perf_domain_grp_idx = |
@@ -626,6 +642,70 @@ done: | |||
626 | return status; | 642 | return status; |
627 | } | 643 | } |
628 | 644 | ||
645 | static u32 clkdomaingetfpoints | ||
646 | ( | ||
647 | struct gk20a *g, | ||
648 | struct clk_pmupstate *pclk, | ||
649 | struct clk_domain *pdomain, | ||
650 | u32 *pfpointscount, | ||
651 | u16 *pfreqpointsinmhz, | ||
652 | u8 rail | ||
653 | ) | ||
654 | { | ||
655 | u32 status = 0; | ||
656 | struct clk_domain_3x_master *p3xmaster = | ||
657 | (struct clk_domain_3x_master *)pdomain; | ||
658 | struct clk_prog *pprog = NULL; | ||
659 | struct clk_prog_1x_master *pprog1xmaster = NULL; | ||
660 | u32 fpointscount = 0; | ||
661 | u32 remainingcount; | ||
662 | u32 totalcount; | ||
663 | u16 *freqpointsdata; | ||
664 | u8 i; | ||
665 | |||
666 | gk20a_dbg_info(""); | ||
667 | |||
668 | if (pfpointscount == NULL) | ||
669 | return -EINVAL; | ||
670 | |||
671 | if ((pfreqpointsinmhz == NULL) && (*pfpointscount != 0)) | ||
672 | return -EINVAL; | ||
673 | |||
674 | if (pdomain->super.implements(g, &pdomain->super, | ||
675 | CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE)) | ||
676 | return -EINVAL; | ||
677 | |||
678 | freqpointsdata = pfreqpointsinmhz; | ||
679 | totalcount = 0; | ||
680 | fpointscount = *pfpointscount; | ||
681 | remainingcount = fpointscount; | ||
682 | /* Iterate over the set of CLK_PROGs pointed at by this domain.*/ | ||
683 | for (i = p3xmaster->super.clk_prog_idx_first; | ||
684 | i <= p3xmaster->super.clk_prog_idx_last; | ||
685 | i++) { | ||
686 | pprog = CLK_CLK_PROG_GET(pclk, i); | ||
687 | pprog1xmaster = (struct clk_prog_1x_master *)pprog; | ||
688 | status = pprog1xmaster->getfpoints(g, pclk, pprog1xmaster, | ||
689 | &fpointscount, &freqpointsdata, rail); | ||
690 | if (status) { | ||
691 | *pfpointscount = 0; | ||
692 | goto done; | ||
693 | } | ||
694 | totalcount += fpointscount; | ||
695 | if (*pfpointscount) { | ||
696 | remainingcount -= fpointscount; | ||
697 | fpointscount = remainingcount; | ||
698 | } else | ||
699 | fpointscount = 0; | ||
700 | |||
701 | } | ||
702 | |||
703 | *pfpointscount = totalcount; | ||
704 | done: | ||
705 | gk20a_dbg_info("done status %x", status); | ||
706 | return status; | ||
707 | } | ||
708 | |||
629 | static u32 _clk_domain_pmudatainit_3x_prog(struct gk20a *g, | 709 | static u32 _clk_domain_pmudatainit_3x_prog(struct gk20a *g, |
630 | struct boardobj *board_obj_ptr, | 710 | struct boardobj *board_obj_ptr, |
631 | struct nv_pmu_boardobj *ppmudata) | 711 | struct nv_pmu_boardobj *ppmudata) |
@@ -689,6 +769,9 @@ static u32 clk_domain_construct_3x_prog(struct gk20a *g, | |||
689 | pdomain->super.super.clkdomainclkvfsearch = | 769 | pdomain->super.super.clkdomainclkvfsearch = |
690 | clkdomainvfsearch; | 770 | clkdomainvfsearch; |
691 | 771 | ||
772 | pdomain->super.super.clkdomainclkgetfpoints = | ||
773 | clkdomaingetfpoints; | ||
774 | |||
692 | pdomain->clk_prog_idx_first = ptmpdomain->clk_prog_idx_first; | 775 | pdomain->clk_prog_idx_first = ptmpdomain->clk_prog_idx_first; |
693 | pdomain->clk_prog_idx_last = ptmpdomain->clk_prog_idx_last; | 776 | pdomain->clk_prog_idx_last = ptmpdomain->clk_prog_idx_last; |
694 | pdomain->noise_unaware_ordering_index = | 777 | pdomain->noise_unaware_ordering_index = |
diff --git a/drivers/gpu/nvgpu/clk/clk_domain.h b/drivers/gpu/nvgpu/clk/clk_domain.h index 07976a2a..eeb7c256 100644 --- a/drivers/gpu/nvgpu/clk/clk_domain.h +++ b/drivers/gpu/nvgpu/clk/clk_domain.h | |||
@@ -33,6 +33,11 @@ typedef u32 clkproglink(struct gk20a *g, struct clk_pmupstate *pclk, | |||
33 | typedef u32 clkvfsearch(struct gk20a *g, struct clk_pmupstate *pclk, | 33 | typedef u32 clkvfsearch(struct gk20a *g, struct clk_pmupstate *pclk, |
34 | struct clk_domain *pdomain, u16 *clkmhz, | 34 | struct clk_domain *pdomain, u16 *clkmhz, |
35 | u32 *voltuv, u8 rail); | 35 | u32 *voltuv, u8 rail); |
36 | |||
37 | typedef u32 clkgetfpoints(struct gk20a *g, struct clk_pmupstate *pclk, | ||
38 | struct clk_domain *pdomain, u32 *pfpointscount, | ||
39 | u16 *pfreqpointsinmhz, u8 rail); | ||
40 | |||
36 | struct clk_domains { | 41 | struct clk_domains { |
37 | struct boardobjgrp_e32 super; | 42 | struct boardobjgrp_e32 super; |
38 | u8 n_num_entries; | 43 | u8 n_num_entries; |
@@ -61,6 +66,7 @@ struct clk_domain { | |||
61 | u8 usage; | 66 | u8 usage; |
62 | clkproglink *clkdomainclkproglink; | 67 | clkproglink *clkdomainclkproglink; |
63 | clkvfsearch *clkdomainclkvfsearch; | 68 | clkvfsearch *clkdomainclkvfsearch; |
69 | clkgetfpoints *clkdomainclkgetfpoints; | ||
64 | }; | 70 | }; |
65 | 71 | ||
66 | struct clk_domain_3x { | 72 | struct clk_domain_3x { |
diff --git a/drivers/gpu/nvgpu/clk/clk_prog.c b/drivers/gpu/nvgpu/clk/clk_prog.c index 5e4700a0..cb9a0e8d 100644 --- a/drivers/gpu/nvgpu/clk/clk_prog.c +++ b/drivers/gpu/nvgpu/clk/clk_prog.c | |||
@@ -30,6 +30,7 @@ static u32 devinit_get_clk_prog_table(struct gk20a *g, | |||
30 | struct clk_progs *pprogobjs); | 30 | struct clk_progs *pprogobjs); |
31 | static vf_flatten vfflatten_prog_1x_master; | 31 | static vf_flatten vfflatten_prog_1x_master; |
32 | static vf_lookup vflookup_prog_1x_master; | 32 | static vf_lookup vflookup_prog_1x_master; |
33 | static get_fpoints getfpoints_prog_1x_master; | ||
33 | 34 | ||
34 | static u32 _clk_progs_pmudatainit(struct gk20a *g, | 35 | static u32 _clk_progs_pmudatainit(struct gk20a *g, |
35 | struct boardobjgrp *pboardobjgrp, | 36 | struct boardobjgrp *pboardobjgrp, |
@@ -607,6 +608,9 @@ static u32 clk_prog_construct_1x_master(struct gk20a *g, | |||
607 | pclkprog->vflookup = | 608 | pclkprog->vflookup = |
608 | vflookup_prog_1x_master; | 609 | vflookup_prog_1x_master; |
609 | 610 | ||
611 | pclkprog->getfpoints = | ||
612 | getfpoints_prog_1x_master; | ||
613 | |||
610 | pclkprog->p_vf_entries = (struct ctrl_clk_clk_prog_1x_master_vf_entry *) | 614 | pclkprog->p_vf_entries = (struct ctrl_clk_clk_prog_1x_master_vf_entry *) |
611 | kzalloc(vfsize, GFP_KERNEL); | 615 | kzalloc(vfsize, GFP_KERNEL); |
612 | 616 | ||
@@ -984,3 +988,60 @@ static u32 vflookup_prog_1x_master | |||
984 | return -EINVAL; | 988 | return -EINVAL; |
985 | return 0; | 989 | return 0; |
986 | } | 990 | } |
991 | |||
992 | static u32 getfpoints_prog_1x_master | ||
993 | ( | ||
994 | struct gk20a *g, | ||
995 | struct clk_pmupstate *pclk, | ||
996 | struct clk_prog_1x_master *p1xmaster, | ||
997 | u32 *pfpointscount, | ||
998 | u16 **ppfreqpointsinmhz, | ||
999 | u8 rail | ||
1000 | ) | ||
1001 | { | ||
1002 | |||
1003 | struct ctrl_clk_clk_prog_1x_master_vf_entry | ||
1004 | *pvfentry; | ||
1005 | struct clk_vf_point *pvfpoint; | ||
1006 | struct clk_progs *pclkprogobjs; | ||
1007 | u8 j; | ||
1008 | u32 fpointscount = 0; | ||
1009 | |||
1010 | if (pfpointscount == NULL) | ||
1011 | return -EINVAL; | ||
1012 | |||
1013 | pclkprogobjs = &(pclk->clk_progobjs); | ||
1014 | |||
1015 | if (pclkprogobjs->vf_entry_count > | ||
1016 | CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES) | ||
1017 | return -EINVAL; | ||
1018 | |||
1019 | if (rail >= pclkprogobjs->vf_entry_count) | ||
1020 | return -EINVAL; | ||
1021 | |||
1022 | pvfentry = p1xmaster->p_vf_entries; | ||
1023 | |||
1024 | pvfentry = (struct ctrl_clk_clk_prog_1x_master_vf_entry *)( | ||
1025 | (u8 *)pvfentry + | ||
1026 | (sizeof(struct ctrl_clk_clk_prog_1x_master_vf_entry) * | ||
1027 | (rail+1))); | ||
1028 | |||
1029 | fpointscount = pvfentry->vf_point_idx_last - | ||
1030 | pvfentry->vf_point_idx_first + 1; | ||
1031 | |||
1032 | /* if pointer for freq data is NULL simply return count */ | ||
1033 | if (*ppfreqpointsinmhz == NULL) | ||
1034 | goto done; | ||
1035 | |||
1036 | if (fpointscount > *pfpointscount) | ||
1037 | return -ENOMEM; | ||
1038 | for (j = pvfentry->vf_point_idx_first; | ||
1039 | j <= pvfentry->vf_point_idx_last; j++) { | ||
1040 | pvfpoint = CLK_CLK_VF_POINT_GET(pclk, j); | ||
1041 | **ppfreqpointsinmhz = clkvfpointfreqmhzget(g, pvfpoint); | ||
1042 | (*ppfreqpointsinmhz)++; | ||
1043 | } | ||
1044 | done: | ||
1045 | *pfpointscount = fpointscount; | ||
1046 | return 0; | ||
1047 | } | ||
diff --git a/drivers/gpu/nvgpu/clk/clk_prog.h b/drivers/gpu/nvgpu/clk/clk_prog.h index 979d327d..be92b3fc 100644 --- a/drivers/gpu/nvgpu/clk/clk_prog.h +++ b/drivers/gpu/nvgpu/clk/clk_prog.h | |||
@@ -32,6 +32,12 @@ typedef u32 vf_lookup(struct gk20a *g, struct clk_pmupstate *pclk, | |||
32 | u8 *slave_clk_domain_idx, u16 *pclkmhz, | 32 | u8 *slave_clk_domain_idx, u16 *pclkmhz, |
33 | u32 *pvoltuv, u8 rail); | 33 | u32 *pvoltuv, u8 rail); |
34 | 34 | ||
35 | typedef u32 get_fpoints(struct gk20a *g, struct clk_pmupstate *pclk, | ||
36 | struct clk_prog_1x_master *p1xmaster, | ||
37 | u32 *pfpointscount, | ||
38 | u16 **ppfreqpointsinmhz, u8 rail); | ||
39 | |||
40 | |||
35 | struct clk_progs { | 41 | struct clk_progs { |
36 | struct boardobjgrp_e255 super; | 42 | struct boardobjgrp_e255 super; |
37 | u8 slave_entry_count; | 43 | u8 slave_entry_count; |
@@ -58,6 +64,7 @@ struct clk_prog_1x_master { | |||
58 | union ctrl_clk_clk_prog_1x_master_source_data source_data; | 64 | union ctrl_clk_clk_prog_1x_master_source_data source_data; |
59 | vf_flatten *vfflatten; | 65 | vf_flatten *vfflatten; |
60 | vf_lookup *vflookup; | 66 | vf_lookup *vflookup; |
67 | get_fpoints *getfpoints; | ||
61 | }; | 68 | }; |
62 | 69 | ||
63 | struct clk_prog_1x_master_ratio { | 70 | struct clk_prog_1x_master_ratio { |