summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/clk/clk_arb.c
diff options
context:
space:
mode:
authorVijayakumar <vsubbu@nvidia.com>2016-10-31 10:49:29 -0400
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:56:52 -0500
commit9664b8e50ab66eb3a690998c4b6541870dd677b6 (patch)
tree0823bfd2183380fb4b18a0cf35ee0d95eaaf73a2 /drivers/gpu/nvgpu/clk/clk_arb.c
parent23ff2eb5c9d498eddd36eb710d4058b23619a0c8 (diff)
gpu: nvgpu: actions before and after vf change
JIRA DNVGPU-175 1)Add functions to be called before and after vf change 2)Capture noise unaware vmin value and pass it as param to vf change functions 3)Before VF change disable CLFC and update noise unware vmin 4)After VF change is done enable CLFC Change-Id: I4bb59fbe96ec5a792e8930db3ab4a39ec74c9a71 Signed-off-by: Vijayakumar <vsubbu@nvidia.com> Reviewed-on: http://git-master/r/1248211 (cherry picked from commit cf07892204d7ce11a0d27ecbc1f5826fbabbde61) Reviewed-on: http://git-master/r/1270950 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'drivers/gpu/nvgpu/clk/clk_arb.c')
-rw-r--r--drivers/gpu/nvgpu/clk/clk_arb.c67
1 files changed, 62 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c
index ee75ce64..762c2466 100644
--- a/drivers/gpu/nvgpu/clk/clk_arb.c
+++ b/drivers/gpu/nvgpu/clk/clk_arb.c
@@ -44,9 +44,17 @@ static void nvgpu_clk_arb_free_session(struct kref *refcount);
44static int nvgpu_clk_arb_change_vf_point(struct gk20a *g, u16 gpc2clk_target, 44static int nvgpu_clk_arb_change_vf_point(struct gk20a *g, u16 gpc2clk_target,
45 u16 sys2clk_target, u16 xbar2clk_target, u16 mclk_target, u32 voltuv, 45 u16 sys2clk_target, u16 xbar2clk_target, u16 mclk_target, u32 voltuv,
46 u32 voltuv_sram); 46 u32 voltuv_sram);
47static int nvgpu_clk_arb_change_vf_point_prefix(struct gk20a *g,
48 u16 gpc2clk_target, u16 sys2clk_target, u16 xbar2clk_target,
49 u16 mclk_target, u32 voltuv, u32 voltuv_sram, u32 nuvmin,
50 u32 nuvmin_sram);
51static int nvgpu_clk_arb_change_vf_point_postfix(struct gk20a *g,
52 u16 gpc2clk_target, u16 sys2clk_target, u16 xbar2clk_target,
53 u16 mclk_target, u32 voltuv, u32 voltuv_sram, u32 nuvmin,
54 u32 nuvmin_sram);
47static u8 nvgpu_clk_arb_find_vf_point(struct nvgpu_clk_arb *arb, 55static u8 nvgpu_clk_arb_find_vf_point(struct nvgpu_clk_arb *arb,
48 u16 *gpc2clk_target, u16 *sys2clk_target, u16 *xbar2clk_target, 56 u16 *gpc2clk, u16 *sys2clk, u16 *xbar2clk, u16 *mclk,
49 u16 *mclk_target, u32 *voltuv, u32 *voltuv_sram); 57 u32 *voltuv, u32 *voltuv_sram, u32 *nuvmin, u32 *nuvmin_sram);
50 58
51#define VF_POINT_INVALID_PSTATE ~0U 59#define VF_POINT_INVALID_PSTATE ~0U
52#define VF_POINT_SET_PSTATE_SUPPORTED(a, b) ((a)->pstates |= (1UL << (b))) 60#define VF_POINT_SET_PSTATE_SUPPORTED(a, b) ((a)->pstates |= (1UL << (b)))
@@ -797,6 +805,7 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
797 u32 pstate = VF_POINT_INVALID_PSTATE; 805 u32 pstate = VF_POINT_INVALID_PSTATE;
798 u32 voltuv, voltuv_sram; 806 u32 voltuv, voltuv_sram;
799 bool mclk_set, gpc2clk_set; 807 bool mclk_set, gpc2clk_set;
808 u32 nuvmin, nuvmin_sram;
800 809
801 int status = 0; 810 int status = 0;
802 811
@@ -879,7 +888,7 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
879 /* Query the table for the closest vf point to program */ 888 /* Query the table for the closest vf point to program */
880 pstate = nvgpu_clk_arb_find_vf_point(arb, &gpc2clk_target, 889 pstate = nvgpu_clk_arb_find_vf_point(arb, &gpc2clk_target,
881 &sys2clk_target, &xbar2clk_target, &mclk_target, &voltuv, 890 &sys2clk_target, &xbar2clk_target, &mclk_target, &voltuv,
882 &voltuv_sram); 891 &voltuv_sram, &nuvmin, &nuvmin_sram);
883 892
884 if (pstate == VF_POINT_INVALID_PSTATE) { 893 if (pstate == VF_POINT_INVALID_PSTATE) {
885 arb->status = -EINVAL; 894 arb->status = -EINVAL;
@@ -897,6 +906,17 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
897 /* Program clocks */ 906 /* Program clocks */
898 /* A change in both mclk of gpc2clk may require a change in voltage */ 907 /* A change in both mclk of gpc2clk may require a change in voltage */
899 908
909 status = nvgpu_clk_arb_change_vf_point_prefix(g, gpc2clk_target,
910 sys2clk_target, xbar2clk_target, mclk_target, voltuv,
911 voltuv_sram, nuvmin, nuvmin_sram);
912
913 if (status < 0) {
914 arb->status = status;
915 /* make status visible */
916 smp_mb();
917 goto exit_arb;
918 }
919
900 status = nvgpu_clk_arb_change_vf_point(g, gpc2clk_target, 920 status = nvgpu_clk_arb_change_vf_point(g, gpc2clk_target,
901 sys2clk_target, xbar2clk_target, mclk_target, voltuv, 921 sys2clk_target, xbar2clk_target, mclk_target, voltuv,
902 voltuv_sram); 922 voltuv_sram);
@@ -905,9 +925,20 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
905 arb->status = status; 925 arb->status = status;
906 /* make status visible */ 926 /* make status visible */
907 smp_mb(); 927 smp_mb();
928 goto exit_arb;
929 }
930
931 status = nvgpu_clk_arb_change_vf_point_postfix(g, gpc2clk_target,
932 sys2clk_target, xbar2clk_target, mclk_target, voltuv,
933 voltuv_sram, nuvmin, nuvmin_sram);
908 934
935 if (status < 0) {
936 arb->status = status;
937 /* make status visible */
938 smp_mb();
909 goto exit_arb; 939 goto exit_arb;
910 } 940 }
941
911 actual = ACCESS_ONCE(arb->actual) == &arb->actual_pool[0] ? 942 actual = ACCESS_ONCE(arb->actual) == &arb->actual_pool[0] ?
912 &arb->actual_pool[1] : &arb->actual_pool[0]; 943 &arb->actual_pool[1] : &arb->actual_pool[0];
913 944
@@ -1189,7 +1220,7 @@ int nvgpu_clk_arb_get_arbiter_clk_f_points(struct gk20a *g,
1189 1220
1190static u8 nvgpu_clk_arb_find_vf_point(struct nvgpu_clk_arb *arb, 1221static u8 nvgpu_clk_arb_find_vf_point(struct nvgpu_clk_arb *arb,
1191 u16 *gpc2clk, u16 *sys2clk, u16 *xbar2clk, u16 *mclk, 1222 u16 *gpc2clk, u16 *sys2clk, u16 *xbar2clk, u16 *mclk,
1192 u32 *voltuv, u32 *voltuv_sram) 1223 u32 *voltuv, u32 *voltuv_sram, u32 *nuvmin, u32 *nuvmin_sram)
1193{ 1224{
1194 u16 gpc2clk_target, mclk_target; 1225 u16 gpc2clk_target, mclk_target;
1195 u32 gpc2clk_voltuv, gpc2clk_voltuv_sram; 1226 u32 gpc2clk_voltuv, gpc2clk_voltuv_sram;
@@ -1301,12 +1332,38 @@ find_exit:
1301 *voltuv = gpc2clk_voltuv > mclk_voltuv ? gpc2clk_voltuv : mclk_voltuv; 1332 *voltuv = gpc2clk_voltuv > mclk_voltuv ? gpc2clk_voltuv : mclk_voltuv;
1302 *voltuv_sram = gpc2clk_voltuv_sram > mclk_voltuv_sram ? 1333 *voltuv_sram = gpc2clk_voltuv_sram > mclk_voltuv_sram ?
1303 gpc2clk_voltuv_sram : mclk_voltuv_sram; 1334 gpc2clk_voltuv_sram : mclk_voltuv_sram;
1304 1335 /* noise unaware vmin */
1336 *nuvmin = mclk_voltuv;
1337 *nuvmin_sram = mclk_voltuv_sram;
1305 *gpc2clk = gpc2clk_target; 1338 *gpc2clk = gpc2clk_target;
1306 *mclk = mclk_target; 1339 *mclk = mclk_target;
1307 return pstate; 1340 return pstate;
1308} 1341}
1309 1342
1343static int nvgpu_clk_arb_change_vf_point_prefix(struct gk20a *g,
1344 u16 gpc2clk_target, u16 sys2clk_target, u16 xbar2clk_target,
1345 u16 mclk_target, u32 voltuv, u32 voltuv_sram, u32 nuvmin,
1346 u32 nuvmin_sram)
1347{
1348
1349 int status;
1350
1351 status = clk_pmu_freq_controller_load(g, false);
1352 if (status < 0)
1353 return status;
1354
1355 status = volt_set_noiseaware_vmin(g, nuvmin, nuvmin_sram);
1356 return status;
1357}
1358
1359static int nvgpu_clk_arb_change_vf_point_postfix(struct gk20a *g,
1360 u16 gpc2clk_target, u16 sys2clk_target, u16 xbar2clk_target,
1361 u16 mclk_target, u32 voltuv, u32 voltuv_sram, u32 nuvmin,
1362 u32 nuvmin_sram)
1363{
1364 return clk_pmu_freq_controller_load(g, true);
1365}
1366
1310static int nvgpu_clk_arb_change_vf_point(struct gk20a *g, u16 gpc2clk_target, 1367static int nvgpu_clk_arb_change_vf_point(struct gk20a *g, u16 gpc2clk_target,
1311 u16 sys2clk_target, u16 xbar2clk_target, u16 mclk_target, u32 voltuv, 1368 u16 sys2clk_target, u16 xbar2clk_target, u16 mclk_target, u32 voltuv,
1312 u32 voltuv_sram) 1369 u32 voltuv_sram)