summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c86
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h4
-rw-r--r--include/uapi/linux/nvgpu.h83
3 files changed, 95 insertions, 78 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
index 8e243eab..9082f861 100644
--- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
@@ -76,7 +76,7 @@ int gk20a_ctrl_dev_release(struct inode *inode, struct file *filp)
76 gk20a_dbg_fn(""); 76 gk20a_dbg_fn("");
77 77
78 if (clk_session) 78 if (clk_session)
79 nvgpu_clk_arb_cleanup_session(g, clk_session); 79 nvgpu_clk_arb_release_session(g, clk_session);
80 kfree(priv); 80 kfree(priv);
81 81
82 return 0; 82 return 0;
@@ -834,6 +834,8 @@ static int nvgpu_gpu_clk_get_vf_points(struct gk20a *g,
834 u32 i; 834 u32 i;
835 u32 max_points = 0; 835 u32 max_points = 0;
836 u32 num_points = 0; 836 u32 num_points = 0;
837 u64 min_hz;
838 u64 max_hz;
837 u16 min_mhz; 839 u16 min_mhz;
838 u16 max_mhz; 840 u16 max_mhz;
839 841
@@ -862,7 +864,7 @@ static int nvgpu_gpu_clk_get_vf_points(struct gk20a *g,
862 return -EINVAL; 864 return -EINVAL;
863 865
864 err = nvgpu_clk_arb_get_arbiter_clk_range(g, args->clk_domain, 866 err = nvgpu_clk_arb_get_arbiter_clk_range(g, args->clk_domain,
865 &min_mhz, &max_mhz); 867 &min_hz, &max_hz);
866 if (err) 868 if (err)
867 return err; 869 return err;
868 870
@@ -879,6 +881,8 @@ static int nvgpu_gpu_clk_get_vf_points(struct gk20a *g,
879 (uintptr_t)args->clk_vf_point_entries; 881 (uintptr_t)args->clk_vf_point_entries;
880 882
881 last_mhz = 0; 883 last_mhz = 0;
884 min_mhz = (u16)(min_hz / (u64)MHZ);
885 max_mhz = (u16)(max_hz / (u64)MHZ);
882 num_points = 0; 886 num_points = 0;
883 for (i = 0; (i < max_points) && !err; i++) { 887 for (i = 0; (i < max_points) && !err; i++) {
884 888
@@ -891,7 +895,7 @@ static int nvgpu_gpu_clk_get_vf_points(struct gk20a *g,
891 continue; 895 continue;
892 896
893 last_mhz = fpoints[i]; 897 last_mhz = fpoints[i];
894 clk_point.freq_mhz = fpoints[i]; 898 clk_point.freq_hz = (u64)fpoints[i] * (u64)MHZ;
895 899
896 err = copy_to_user((void __user *)entry, &clk_point, 900 err = copy_to_user((void __user *)entry, &clk_point,
897 sizeof(clk_point)); 901 sizeof(clk_point));
@@ -919,7 +923,6 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g,
919 u32 num_domains; 923 u32 num_domains;
920 u32 i; 924 u32 i;
921 int bit; 925 int bit;
922 u16 min_mhz, max_mhz;
923 int err; 926 int err;
924 927
925 gk20a_dbg_fn(""); 928 gk20a_dbg_fn("");
@@ -963,15 +966,13 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g,
963 clk_domains &= ~BIT(bit); 966 clk_domains &= ~BIT(bit);
964 } 967 }
965 968
969 clk_range.flags = 0;
966 err = nvgpu_clk_arb_get_arbiter_clk_range(g, 970 err = nvgpu_clk_arb_get_arbiter_clk_range(g,
967 clk_range.clk_domain, &min_mhz, &max_mhz); 971 clk_range.clk_domain,
972 &clk_range.min_hz, &clk_range.max_hz);
968 if (err) 973 if (err)
969 return err; 974 return err;
970 975
971 clk_range.min_mhz = min_mhz;
972 clk_range.max_mhz = max_mhz;
973 clk_range.flags = 0;
974
975 err = copy_to_user(entry, &clk_range, sizeof(clk_range)); 976 err = copy_to_user(entry, &clk_range, sizeof(clk_range));
976 if (err) 977 if (err)
977 return -EFAULT; 978 return -EFAULT;
@@ -992,7 +993,6 @@ static int nvgpu_gpu_clk_set_info(struct gk20a *g,
992 struct nvgpu_clk_session *session = priv->clk_session; 993 struct nvgpu_clk_session *session = priv->clk_session;
993 u32 clk_domains = 0; 994 u32 clk_domains = 0;
994 u32 i; 995 u32 i;
995 int fd;
996 996
997 gk20a_dbg_fn(""); 997 gk20a_dbg_fn("");
998 998
@@ -1003,10 +1003,6 @@ static int nvgpu_gpu_clk_set_info(struct gk20a *g,
1003 if (!clk_domains) 1003 if (!clk_domains)
1004 return -EINVAL; 1004 return -EINVAL;
1005 1005
1006 fd = nvgpu_clk_arb_install_session_fd(g, session);
1007 if (fd < 0)
1008 return fd;
1009
1010 entry = (struct nvgpu_gpu_clk_info __user *) 1006 entry = (struct nvgpu_gpu_clk_info __user *)
1011 (uintptr_t)args->clk_info_entries; 1007 (uintptr_t)args->clk_info_entries;
1012 1008
@@ -1031,16 +1027,12 @@ static int nvgpu_gpu_clk_set_info(struct gk20a *g,
1031 sizeof(clk_info))) 1027 sizeof(clk_info)))
1032 return -EFAULT; 1028 return -EFAULT;
1033 1029
1034 nvgpu_clk_arb_set_session_target_mhz(session, 1030 nvgpu_clk_arb_set_session_target_hz(session,
1035 clk_info.clk_domain, clk_info.target_mhz); 1031 clk_info.clk_domain, clk_info.freq_hz);
1036 } 1032 }
1037 1033
1038 nvgpu_clk_arb_apply_session_constraints(g, session); 1034 return nvgpu_clk_arb_apply_session_constraints(g, session,
1039 1035 &args->completion_fd);
1040 args->req_nr = nvgpu_clk_arb_get_session_req_nr(g, session);
1041 args->fd = fd;
1042
1043 return 0;
1044} 1036}
1045 1037
1046 1038
@@ -1053,8 +1045,6 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g,
1053 struct nvgpu_clk_session *session = priv->clk_session; 1045 struct nvgpu_clk_session *session = priv->clk_session;
1054 u32 clk_domains = 0; 1046 u32 clk_domains = 0;
1055 u32 num_domains; 1047 u32 num_domains;
1056 u16 actual_mhz;
1057 u16 target_mhz;
1058 u32 i; 1048 u32 i;
1059 int err; 1049 int err;
1060 int bit; 1050 int bit;
@@ -1064,8 +1054,6 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g,
1064 if (!session) 1054 if (!session)
1065 return -EINVAL; 1055 return -EINVAL;
1066 1056
1067 args->last_req_nr = nvgpu_clk_arb_get_arbiter_req_nr(g);
1068
1069 if (!args->flags) { 1057 if (!args->flags) {
1070 clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g); 1058 clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g);
1071 num_domains = hweight_long(clk_domains); 1059 num_domains = hweight_long(clk_domains);
@@ -1100,20 +1088,29 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g,
1100 bit = ffs(clk_domains) - 1; 1088 bit = ffs(clk_domains) - 1;
1101 clk_info.clk_domain = BIT(bit); 1089 clk_info.clk_domain = BIT(bit);
1102 clk_domains &= ~BIT(bit); 1090 clk_domains &= ~BIT(bit);
1091 clk_info.clk_type = args->clk_type;
1103 } 1092 }
1104 1093
1105 err = nvgpu_clk_arb_get_arbiter_actual_mhz(g, 1094 switch (clk_info.clk_type) {
1106 clk_info.clk_domain, &actual_mhz); 1095 case NVGPU_GPU_CLK_TYPE_TARGET:
1107 if (err) 1096 err = nvgpu_clk_arb_get_session_target_hz(session,
1108 return err; 1097 clk_info.clk_domain, &clk_info.freq_hz);
1109 1098 break;
1110 err = nvgpu_clk_arb_get_session_target_mhz(session, 1099 case NVGPU_GPU_CLK_TYPE_ACTUAL:
1111 clk_info.clk_domain, &target_mhz); 1100 err = nvgpu_clk_arb_get_arbiter_actual_hz(g,
1101 clk_info.clk_domain, &clk_info.freq_hz);
1102 break;
1103 case NVGPU_GPU_CLK_TYPE_EFFECTIVE:
1104 err = nvgpu_clk_arb_get_arbiter_effective_hz(g,
1105 clk_info.clk_domain, &clk_info.freq_hz);
1106 break;
1107 default:
1108 err = -EINVAL;
1109 break;
1110 }
1112 if (err) 1111 if (err)
1113 return err; 1112 return err;
1114 1113
1115 clk_info.actual_mhz = actual_mhz;
1116 clk_info.target_mhz = target_mhz;
1117 clk_info.flags = 0; 1114 clk_info.flags = 0;
1118 1115
1119 err = copy_to_user((void __user *)entry, &clk_info, 1116 err = copy_to_user((void __user *)entry, &clk_info,
@@ -1127,6 +1124,20 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g,
1127 return 0; 1124 return 0;
1128} 1125}
1129 1126
1127static int nvgpu_gpu_clk_get_event_fd(struct gk20a *g,
1128 struct gk20a_ctrl_priv *priv,
1129 struct nvgpu_gpu_clk_get_event_fd_args *args)
1130{
1131 struct nvgpu_clk_session *session = priv->clk_session;
1132
1133 gk20a_dbg_fn("");
1134
1135 if (!session || args->flags)
1136 return -EINVAL;
1137
1138 return nvgpu_clk_arb_install_event_fd(g, session, &args->event_fd);
1139}
1140
1130long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 1141long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1131{ 1142{
1132 struct gk20a_ctrl_priv *priv = filp->private_data; 1143 struct gk20a_ctrl_priv *priv = filp->private_data;
@@ -1409,6 +1420,11 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg
1409 (struct nvgpu_gpu_clk_get_info_args *)buf); 1420 (struct nvgpu_gpu_clk_get_info_args *)buf);
1410 break; 1421 break;
1411 1422
1423 case NVGPU_GPU_IOCTL_CLK_GET_EVENT_FD:
1424 err = nvgpu_gpu_clk_get_event_fd(g, priv,
1425 (struct nvgpu_gpu_clk_get_event_fd_args *)buf);
1426 break;
1427
1412 default: 1428 default:
1413 dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd); 1429 dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd);
1414 err = -ENOTTY; 1430 err = -ENOTTY;
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 564026a4..3d55304b 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -636,9 +636,9 @@ struct gpu_ops {
636 struct { 636 struct {
637 u32 (*get_arbiter_clk_domains)(struct gk20a *g); 637 u32 (*get_arbiter_clk_domains)(struct gk20a *g);
638 int (*get_arbiter_clk_range)(struct gk20a *g, u32 api_domain, 638 int (*get_arbiter_clk_range)(struct gk20a *g, u32 api_domain,
639 u16 *min_mhz, u16 *max_mhz); 639 u64 *min_hz, u64 *max_hz);
640 int (*get_arbiter_clk_default)(struct gk20a *g, u32 api_domain, 640 int (*get_arbiter_clk_default)(struct gk20a *g, u32 api_domain,
641 u16 *default_mhz); 641 u64 *default_hz);
642 } clk_arb; 642 } clk_arb;
643 bool privsecurity; 643 bool privsecurity;
644 bool securegpccs; 644 bool securegpccs;
diff --git a/include/uapi/linux/nvgpu.h b/include/uapi/linux/nvgpu.h
index 2d044db4..49e3fc5c 100644
--- a/include/uapi/linux/nvgpu.h
+++ b/include/uapi/linux/nvgpu.h
@@ -520,8 +520,8 @@ struct nvgpu_gpu_clk_range {
520 520
521 /* NVGPU_GPU_CLK_DOMAIN_* */ 521 /* NVGPU_GPU_CLK_DOMAIN_* */
522 __u32 clk_domain; 522 __u32 clk_domain;
523 __u32 min_mhz; 523 __u64 min_hz;
524 __u32 max_mhz; 524 __u64 max_hz;
525}; 525};
526 526
527/* Request on specific clock domains */ 527/* Request on specific clock domains */
@@ -551,10 +551,7 @@ struct nvgpu_gpu_clk_range_args {
551}; 551};
552 552
553struct nvgpu_gpu_clk_vf_point { 553struct nvgpu_gpu_clk_vf_point {
554 554 __u64 freq_hz;
555 /* Flags (not currently used) */
556 __u32 flags;
557 __u32 freq_mhz;
558}; 555};
559 556
560struct nvgpu_gpu_clk_vf_points_args { 557struct nvgpu_gpu_clk_vf_points_args {
@@ -569,7 +566,7 @@ struct nvgpu_gpu_clk_vf_points_args {
569 clk_vf_point_entries. If max_entries is zero, 566 clk_vf_point_entries. If max_entries is zero,
570 NVGPU_GPU_IOCTL_CLK_GET_VF_POINTS will return 0 and max_entries will 567 NVGPU_GPU_IOCTL_CLK_GET_VF_POINTS will return 0 and max_entries will
571 be set to the max number of VF entries for this clock domain. If 568 be set to the max number of VF entries for this clock domain. If
572 there are more entries than max_entires, then ioctl will return 569 there are more entries than max_entries, then ioctl will return
573 -EINVAL. 570 -EINVAL.
574 */ 571 */
575 __u16 max_entries; 572 __u16 max_entries;
@@ -588,24 +585,31 @@ struct nvgpu_gpu_clk_vf_points_args {
588 __u64 clk_vf_point_entries; 585 __u64 clk_vf_point_entries;
589}; 586};
590 587
588/* Target clock requested by application*/
589#define NVGPU_GPU_CLK_TYPE_TARGET 1
590/* Actual clock frequency for the domain.
591 May deviate from desired target frequency due to PLL constraints. */
592#define NVGPU_GPU_CLK_TYPE_ACTUAL 2
593/* Effective clock, measured from hardware */
594#define NVGPU_GPU_CLK_TYPE_EFFECTIVE 3
595
591struct nvgpu_gpu_clk_info { 596struct nvgpu_gpu_clk_info {
592 597
593 /* Flags (not currently used) */ 598 /* Flags (not currently used) */
594 __u32 flags; 599 __u16 flags;
595 600
596 /* NVGPU_GPU_CLK_DOMAIN_* */ 601 /* in: When NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS set, indicates
597 __u32 clk_domain; 602 the type of clock info to be returned for this entry. It is
603 allowed to have several entries with different clock types in
604 the same request (for instance query both target and actual
605 clocks for a given clock domain). This field is ignored for a
606 SET operation. */
607 __u16 clk_type;
598 608
599 /* target clock frequency for the domain in MHz. Should be 609 /* NVGPU_GPU_CLK_DOMAIN_xxx */
600 specified with a non-zero value in NVGPU_GPU_IOCTL_CLK_SET_INFO. 610 __u32 clk_domain;
601 */
602 __u32 target_mhz;
603 611
604 /* actual clock frequency for the domain in MHz. This value 612 __u64 freq_hz;
605 may deviate from the desired target frequency due to PLL constraints.
606 Not used in NVGPU_GPU_IOCTL_CLK_SET_INFO.
607 */
608 __u32 actual_mhz;
609}; 613};
610 614
611struct nvgpu_gpu_clk_get_info_args { 615struct nvgpu_gpu_clk_get_info_args {
@@ -617,7 +621,11 @@ struct nvgpu_gpu_clk_get_info_args {
617 */ 621 */
618 __u32 flags; 622 __u32 flags;
619 623
620 __u16 pad0; 624 /* in: indicates which type of clock info to be returned (see
625 NVGPU_GPU_CLK_TYPE_xxx). If NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS
626 is defined, clk_type is specified in each clock info entry instead.
627 */
628 __u16 clk_type;
621 629
622 /* in/out: Number of clock info entries contained in clk_info_entries. 630 /* in/out: Number of clock info entries contained in clk_info_entries.
623 If zero, NVGPU_GPU_IOCTL_CLK_GET_INFO will return 0 and 631 If zero, NVGPU_GPU_IOCTL_CLK_GET_INFO will return 0 and
@@ -639,12 +647,6 @@ struct nvgpu_gpu_clk_get_info_args {
639 */ 647 */
640 __u64 clk_info_entries; 648 __u64 clk_info_entries;
641 649
642 __u32 pad1;
643
644 /* out: sequence number of last processed request. sequence numbers
645 are per-user.
646 */
647 __u32 last_req_nr;
648}; 650};
649 651
650struct nvgpu_gpu_clk_set_info_args { 652struct nvgpu_gpu_clk_set_info_args {
@@ -665,24 +667,21 @@ struct nvgpu_gpu_clk_set_info_args {
665 */ 667 */
666 __u64 clk_info_entries; 668 __u64 clk_info_entries;
667 669
668 /* out: File descriptor for completions and event notifications. 670 /* out: File descriptor for request completion. Application can poll
669 If application does not close this fd after completion, then the 671 this file descriptor to determine when the request has completed.
670 same fd will be returned for subsequent request (recommended). 672 The fd must be closed afterwards.
671 */ 673 */
672 int fd; 674 int completion_fd;
673
674 /* out: sequence number for this request. In order to determine that
675 a request has completed, an application should check this sequence
676 number against last_req_nr from NVGPU_GPU_IOCTL_CLK_GET_INFO, using
677 nvgpu_clk_req_complete(req_nr, last_req_nr);
678 */
679 __u32 req_nr;
680}; 675};
681 676
682static inline int nvgpu_clk_req_complete(__u32 req_nr, __u32 last_req_nr) 677struct nvgpu_gpu_clk_get_event_fd_args {
683{ 678
684 return ((long)(last_req_nr - req_nr) >= 0); 679 /* in: Flags (not currently used). */
685} 680 __u32 flags;
681
682 /* out: File descriptor for events, i.e. any clock update. */
683 int event_fd;
684};
686 685
687struct nvgpu_gpu_get_memory_state_args { 686struct nvgpu_gpu_get_memory_state_args {
688 /* 687 /*
@@ -778,6 +777,8 @@ struct nvgpu_gpu_get_fbp_l2_masks_args {
778 _IOWR(NVGPU_GPU_IOCTL_MAGIC, 30, struct nvgpu_gpu_clk_get_info_args) 777 _IOWR(NVGPU_GPU_IOCTL_MAGIC, 30, struct nvgpu_gpu_clk_get_info_args)
779#define NVGPU_GPU_IOCTL_CLK_SET_INFO \ 778#define NVGPU_GPU_IOCTL_CLK_SET_INFO \
780 _IOWR(NVGPU_GPU_IOCTL_MAGIC, 31, struct nvgpu_gpu_clk_set_info_args) 779 _IOWR(NVGPU_GPU_IOCTL_MAGIC, 31, struct nvgpu_gpu_clk_set_info_args)
780#define NVGPU_GPU_IOCTL_CLK_GET_EVENT_FD \
781 _IOWR(NVGPU_GPU_IOCTL_MAGIC, 32, struct nvgpu_gpu_clk_get_event_fd_args)
781#define NVGPU_GPU_IOCTL_GET_MEMORY_STATE \ 782#define NVGPU_GPU_IOCTL_GET_MEMORY_STATE \
782 _IOWR(NVGPU_GPU_IOCTL_MAGIC, 33, \ 783 _IOWR(NVGPU_GPU_IOCTL_MAGIC, 33, \
783 struct nvgpu_gpu_get_memory_state_args) 784 struct nvgpu_gpu_get_memory_state_args)