summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/clk/clk_arb.c
diff options
context:
space:
mode:
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)