summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/clk/clk_arb.c
diff options
context:
space:
mode:
authorMahantesh Kumbar <mkumbar@nvidia.com>2016-11-03 11:46:21 -0400
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:56:53 -0500
commite5824d8014c321fbe2c1e04e12307125dd50a472 (patch)
tree82657cd43c0dcd313b3251f3776e5e80b488fabc /drivers/gpu/nvgpu/clk/clk_arb.c
parent62d13e613807e9bce3a9d1ef0c61725ef3a885ce (diff)
gpu: nvgpu: MSCG support
- update gp106 pg engine init/list/features HALs to support MS engine - Added defines & interface for lpwr tables read from vbios. - lpwr module which reads idx/gr/ms table from vbios to map rppg/mscg support with respective p-state - lpwr module public functions to control lpwr features enable/disable mscg/rppg & mclk-change request whenever change in mclk-change parameters - lpwr public functions to know rppg/mscg support for requested pstate, - added mutex t prevent PG transition while arbiter executes pstate transition - nvgpu_clk_arb_get_current_pstate() of clk arbiter to get current pstate JIRA DNVGPU-71 Change-Id: Ifcd640cc19ef630be1e2a9ba07ec84023d8202a0 Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: http://git-master/r/1247553 (cherry picked from commit 8a441dea2410e1b5196ef24e56a7768b6980e46b) Reviewed-on: http://git-master/r/1270989 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/clk/clk_arb.c')
-rw-r--r--drivers/gpu/nvgpu/clk/clk_arb.c102
1 files changed, 62 insertions, 40 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c
index 3f35fac7..c440dc3b 100644
--- a/drivers/gpu/nvgpu/clk/clk_arb.c
+++ b/drivers/gpu/nvgpu/clk/clk_arb.c
@@ -44,14 +44,6 @@ 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);
55static u8 nvgpu_clk_arb_find_vf_point(struct nvgpu_clk_arb *arb, 47static u8 nvgpu_clk_arb_find_vf_point(struct nvgpu_clk_arb *arb,
56 u16 *gpc2clk, u16 *sys2clk, u16 *xbar2clk, u16 *mclk, 48 u16 *gpc2clk, u16 *sys2clk, u16 *xbar2clk, u16 *mclk,
57 u32 *voltuv, u32 *voltuv_sram, u32 *nuvmin, u32 *nuvmin_sram); 49 u32 *voltuv, u32 *voltuv_sram, u32 *nuvmin, u32 *nuvmin_sram);
@@ -105,6 +97,7 @@ struct nvgpu_clk_arb {
105 spinlock_t sessions_lock; 97 spinlock_t sessions_lock;
106 spinlock_t users_lock; 98 spinlock_t users_lock;
107 99
100 struct mutex pstate_lock;
108 struct list_head users; 101 struct list_head users;
109 struct list_head sessions; 102 struct list_head sessions;
110 struct llist_head requests; 103 struct llist_head requests;
@@ -235,6 +228,7 @@ int nvgpu_clk_arb_init_arbiter(struct gk20a *g)
235 g->clk_arb = arb; 228 g->clk_arb = arb;
236 arb->g = g; 229 arb->g = g;
237 230
231 mutex_init(&arb->pstate_lock);
238 spin_lock_init(&arb->sessions_lock); 232 spin_lock_init(&arb->sessions_lock);
239 spin_lock_init(&arb->users_lock); 233 spin_lock_init(&arb->users_lock);
240 234
@@ -943,12 +937,23 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
943 /* Program clocks */ 937 /* Program clocks */
944 /* A change in both mclk of gpc2clk may require a change in voltage */ 938 /* A change in both mclk of gpc2clk may require a change in voltage */
945 939
946 status = nvgpu_clk_arb_change_vf_point_prefix(g, gpc2clk_target, 940 mutex_lock(&arb->pstate_lock);
947 sys2clk_target, xbar2clk_target, mclk_target, voltuv, 941 status = nvgpu_lpwr_disable_pg(g, false);
948 voltuv_sram, nuvmin, nuvmin_sram);
949 942
943 status = clk_pmu_freq_controller_load(g, false);
944 if (status < 0) {
945 arb->status = status;
946 mutex_unlock(&arb->pstate_lock);
947
948 /* make status visible */
949 smp_mb();
950 goto exit_arb;
951 }
952 status = volt_set_noiseaware_vmin(g, nuvmin, nuvmin_sram);
950 if (status < 0) { 953 if (status < 0) {
951 arb->status = status; 954 arb->status = status;
955 mutex_unlock(&arb->pstate_lock);
956
952 /* make status visible */ 957 /* make status visible */
953 smp_mb(); 958 smp_mb();
954 goto exit_arb; 959 goto exit_arb;
@@ -957,20 +962,30 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
957 status = nvgpu_clk_arb_change_vf_point(g, gpc2clk_target, 962 status = nvgpu_clk_arb_change_vf_point(g, gpc2clk_target,
958 sys2clk_target, xbar2clk_target, mclk_target, voltuv, 963 sys2clk_target, xbar2clk_target, mclk_target, voltuv,
959 voltuv_sram); 964 voltuv_sram);
960
961 if (status < 0) { 965 if (status < 0) {
962 arb->status = status; 966 arb->status = status;
967 mutex_unlock(&arb->pstate_lock);
968
963 /* make status visible */ 969 /* make status visible */
964 smp_mb(); 970 smp_mb();
965 goto exit_arb; 971 goto exit_arb;
966 } 972 }
967 973
968 status = nvgpu_clk_arb_change_vf_point_postfix(g, gpc2clk_target, 974 status = clk_pmu_freq_controller_load(g, true);
969 sys2clk_target, xbar2clk_target, mclk_target, voltuv, 975 if (status < 0) {
970 voltuv_sram, nuvmin, nuvmin_sram); 976 arb->status = status;
977 mutex_unlock(&arb->pstate_lock);
978
979 /* make status visible */
980 smp_mb();
981 goto exit_arb;
982 }
971 983
984 status = nvgpu_lwpr_mclk_change(g, pstate);
972 if (status < 0) { 985 if (status < 0) {
973 arb->status = status; 986 arb->status = status;
987 mutex_unlock(&arb->pstate_lock);
988
974 /* make status visible */ 989 /* make status visible */
975 smp_mb(); 990 smp_mb();
976 goto exit_arb; 991 goto exit_arb;
@@ -991,15 +1006,24 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
991 smp_wmb(); 1006 smp_wmb();
992 xchg(&arb->actual, actual); 1007 xchg(&arb->actual, actual);
993 1008
1009 status = nvgpu_lpwr_enable_pg(g, false);
1010 if (status < 0) {
1011 arb->status = status;
1012 mutex_unlock(&arb->pstate_lock);
1013
1014 /* make status visible */
1015 smp_mb();
1016 goto exit_arb;
1017 }
1018
994 /* status must be visible before atomic inc */ 1019 /* status must be visible before atomic inc */
995 smp_wmb(); 1020 smp_wmb();
996 atomic_inc(&arb->req_nr); 1021 atomic_inc(&arb->req_nr);
997 1022
998 wake_up_interruptible(&arb->request_wq); 1023 /* Unlock pstate change for PG */
1024 mutex_unlock(&arb->pstate_lock);
999 1025
1000 if (status < 0) 1026 wake_up_interruptible(&arb->request_wq);
1001 gk20a_err(dev_from_gk20a(g),
1002 "Error in arbiter update");
1003 1027
1004#ifdef CONFIG_DEBUG_FS 1028#ifdef CONFIG_DEBUG_FS
1005 g->ops.read_ptimer(g, &t1); 1029 g->ops.read_ptimer(g, &t1);
@@ -1036,6 +1060,9 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
1036#endif 1060#endif
1037 1061
1038exit_arb: 1062exit_arb:
1063 if (status < 0)
1064 gk20a_err(dev_from_gk20a(g),
1065 "Error in arbiter update");
1039 1066
1040 /* notify completion for all requests */ 1067 /* notify completion for all requests */
1041 head = llist_del_all(&arb->requests); 1068 head = llist_del_all(&arb->requests);
@@ -1300,6 +1327,7 @@ recalculate_vf_point:
1300 } 1327 }
1301 if (index == table->mclk_num_points) { 1328 if (index == table->mclk_num_points) {
1302 mclk_vf = &table->mclk_points[index-1]; 1329 mclk_vf = &table->mclk_points[index-1];
1330 index = table->mclk_num_points - 1;
1303 } 1331 }
1304 index_mclk = index; 1332 index_mclk = index;
1305 1333
@@ -1378,28 +1406,11 @@ find_exit:
1378 return pstate; 1406 return pstate;
1379} 1407}
1380 1408
1381static int nvgpu_clk_arb_change_vf_point_prefix(struct gk20a *g, 1409/* This function is inherently unsafe to call while arbiter is running
1382 u16 gpc2clk_target, u16 sys2clk_target, u16 xbar2clk_target, 1410 * arbiter must be blocked before calling this function */
1383 u16 mclk_target, u32 voltuv, u32 voltuv_sram, u32 nuvmin, 1411int nvgpu_clk_arb_get_current_pstate(struct gk20a *g)
1384 u32 nuvmin_sram)
1385{
1386
1387 int status;
1388
1389 status = clk_pmu_freq_controller_load(g, false);
1390 if (status < 0)
1391 return status;
1392
1393 status = volt_set_noiseaware_vmin(g, nuvmin, nuvmin_sram);
1394 return status;
1395}
1396
1397static int nvgpu_clk_arb_change_vf_point_postfix(struct gk20a *g,
1398 u16 gpc2clk_target, u16 sys2clk_target, u16 xbar2clk_target,
1399 u16 mclk_target, u32 voltuv, u32 voltuv_sram, u32 nuvmin,
1400 u32 nuvmin_sram)
1401{ 1412{
1402 return clk_pmu_freq_controller_load(g, true); 1413 return ACCESS_ONCE(g->clk_arb->actual->pstate);
1403} 1414}
1404 1415
1405static int nvgpu_clk_arb_change_vf_point(struct gk20a *g, u16 gpc2clk_target, 1416static int nvgpu_clk_arb_change_vf_point(struct gk20a *g, u16 gpc2clk_target,
@@ -1456,6 +1467,17 @@ static int nvgpu_clk_arb_change_vf_point(struct gk20a *g, u16 gpc2clk_target,
1456 return 0; 1467 return 0;
1457} 1468}
1458 1469
1470void nvgpu_clk_arb_pstate_change_lock(struct gk20a *g, bool lock)
1471{
1472 struct nvgpu_clk_arb *arb = g->clk_arb;
1473
1474 if (lock)
1475 mutex_lock(&arb->pstate_lock);
1476 else
1477 mutex_unlock(&arb->pstate_lock);
1478
1479}
1480
1459#ifdef CONFIG_DEBUG_FS 1481#ifdef CONFIG_DEBUG_FS
1460static int nvgpu_clk_arb_stats_show(struct seq_file *s, void *unused) 1482static int nvgpu_clk_arb_stats_show(struct seq_file *s, void *unused)
1461{ 1483{