diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index aaadd186..3de84851 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | |||
@@ -32,6 +32,10 @@ | |||
32 | #include "hw_timer_gk20a.h" | 32 | #include "hw_timer_gk20a.h" |
33 | 33 | ||
34 | 34 | ||
35 | #define HZ_TO_MHZ(a) ((a > 0xF414F9CD7) ? 0xffff : (a >> 32) ? \ | ||
36 | (u32) ((a * 0x10C8ULL) >> 32) : (u16) ((u32) a/MHZ)) | ||
37 | #define MHZ_TO_HZ(a) ((u64)a * MHZ) | ||
38 | |||
35 | struct gk20a_ctrl_priv { | 39 | struct gk20a_ctrl_priv { |
36 | struct device *dev; | 40 | struct device *dev; |
37 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC | 41 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC |
@@ -840,8 +844,6 @@ static int nvgpu_gpu_clk_get_vf_points(struct gk20a *g, | |||
840 | u32 i; | 844 | u32 i; |
841 | u32 max_points = 0; | 845 | u32 max_points = 0; |
842 | u32 num_points = 0; | 846 | u32 num_points = 0; |
843 | u64 min_hz; | ||
844 | u64 max_hz; | ||
845 | u16 min_mhz; | 847 | u16 min_mhz; |
846 | u16 max_mhz; | 848 | u16 max_mhz; |
847 | 849 | ||
@@ -870,7 +872,7 @@ static int nvgpu_gpu_clk_get_vf_points(struct gk20a *g, | |||
870 | return -EINVAL; | 872 | return -EINVAL; |
871 | 873 | ||
872 | err = nvgpu_clk_arb_get_arbiter_clk_range(g, args->clk_domain, | 874 | err = nvgpu_clk_arb_get_arbiter_clk_range(g, args->clk_domain, |
873 | &min_hz, &max_hz); | 875 | &min_mhz, &max_mhz); |
874 | if (err) | 876 | if (err) |
875 | return err; | 877 | return err; |
876 | 878 | ||
@@ -887,8 +889,6 @@ static int nvgpu_gpu_clk_get_vf_points(struct gk20a *g, | |||
887 | (uintptr_t)args->clk_vf_point_entries; | 889 | (uintptr_t)args->clk_vf_point_entries; |
888 | 890 | ||
889 | last_mhz = 0; | 891 | last_mhz = 0; |
890 | min_mhz = (u16)(min_hz / (u64)MHZ); | ||
891 | max_mhz = (u16)(max_hz / (u64)MHZ); | ||
892 | num_points = 0; | 892 | num_points = 0; |
893 | for (i = 0; (i < max_points) && !err; i++) { | 893 | for (i = 0; (i < max_points) && !err; i++) { |
894 | 894 | ||
@@ -901,7 +901,7 @@ static int nvgpu_gpu_clk_get_vf_points(struct gk20a *g, | |||
901 | continue; | 901 | continue; |
902 | 902 | ||
903 | last_mhz = fpoints[i]; | 903 | last_mhz = fpoints[i]; |
904 | clk_point.freq_hz = (u64)fpoints[i] * (u64)MHZ; | 904 | clk_point.freq_hz = MHZ_TO_HZ(fpoints[i]); |
905 | 905 | ||
906 | err = copy_to_user((void __user *)entry, &clk_point, | 906 | err = copy_to_user((void __user *)entry, &clk_point, |
907 | sizeof(clk_point)); | 907 | sizeof(clk_point)); |
@@ -931,6 +931,7 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g, | |||
931 | u32 i; | 931 | u32 i; |
932 | int bit; | 932 | int bit; |
933 | int err; | 933 | int err; |
934 | u16 min_mhz, max_mhz; | ||
934 | 935 | ||
935 | gk20a_dbg_fn(""); | 936 | gk20a_dbg_fn(""); |
936 | 937 | ||
@@ -979,7 +980,10 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g, | |||
979 | clk_range.flags = 0; | 980 | clk_range.flags = 0; |
980 | err = nvgpu_clk_arb_get_arbiter_clk_range(g, | 981 | err = nvgpu_clk_arb_get_arbiter_clk_range(g, |
981 | clk_range.clk_domain, | 982 | clk_range.clk_domain, |
982 | &clk_range.min_hz, &clk_range.max_hz); | 983 | &min_mhz, &max_mhz); |
984 | clk_range.min_hz = MHZ_TO_HZ(min_mhz); | ||
985 | clk_range.max_hz = MHZ_TO_HZ(max_mhz); | ||
986 | |||
983 | if (err) | 987 | if (err) |
984 | return err; | 988 | return err; |
985 | 989 | ||
@@ -1001,8 +1005,12 @@ static int nvgpu_gpu_clk_set_info(struct gk20a *g, | |||
1001 | struct nvgpu_gpu_clk_info clk_info; | 1005 | struct nvgpu_gpu_clk_info clk_info; |
1002 | struct nvgpu_gpu_clk_info __user *entry; | 1006 | struct nvgpu_gpu_clk_info __user *entry; |
1003 | struct nvgpu_clk_session *session = priv->clk_session; | 1007 | struct nvgpu_clk_session *session = priv->clk_session; |
1008 | |||
1009 | int fd; | ||
1004 | u32 clk_domains = 0; | 1010 | u32 clk_domains = 0; |
1005 | u32 i; | 1011 | u16 freq_mhz; |
1012 | int i; | ||
1013 | int ret; | ||
1006 | 1014 | ||
1007 | gk20a_dbg_fn(""); | 1015 | gk20a_dbg_fn(""); |
1008 | 1016 | ||
@@ -1031,18 +1039,28 @@ static int nvgpu_gpu_clk_set_info(struct gk20a *g, | |||
1031 | entry = (struct nvgpu_gpu_clk_info __user *) | 1039 | entry = (struct nvgpu_gpu_clk_info __user *) |
1032 | (uintptr_t)args->clk_info_entries; | 1040 | (uintptr_t)args->clk_info_entries; |
1033 | 1041 | ||
1042 | ret = nvgpu_clk_arb_install_request_fd(g, session, &fd); | ||
1043 | if (ret < 0) | ||
1044 | return ret; | ||
1045 | |||
1034 | for (i = 0; i < args->num_entries; i++, entry++) { | 1046 | for (i = 0; i < args->num_entries; i++, entry++) { |
1035 | 1047 | ||
1036 | if (copy_from_user(&clk_info, (void __user *)entry, | 1048 | if (copy_from_user(&clk_info, (void __user *)entry, |
1037 | sizeof(clk_info))) | 1049 | sizeof(clk_info))) |
1038 | return -EFAULT; | 1050 | return -EFAULT; |
1051 | freq_mhz = HZ_TO_MHZ(clk_info.freq_hz); | ||
1039 | 1052 | ||
1040 | nvgpu_clk_arb_set_session_target_hz(session, | 1053 | nvgpu_clk_arb_set_session_target_mhz(session, fd, |
1041 | clk_info.clk_domain, clk_info.freq_hz); | 1054 | clk_info.clk_domain, freq_mhz); |
1042 | } | 1055 | } |
1043 | 1056 | ||
1044 | return nvgpu_clk_arb_apply_session_constraints(g, session, | 1057 | ret = nvgpu_clk_arb_commit_request_fd(g, session, fd); |
1045 | &args->completion_fd); | 1058 | if (ret < 0) |
1059 | return ret; | ||
1060 | |||
1061 | args->completion_fd = fd; | ||
1062 | |||
1063 | return ret; | ||
1046 | } | 1064 | } |
1047 | 1065 | ||
1048 | 1066 | ||
@@ -1057,6 +1075,7 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g, | |||
1057 | u32 num_domains; | 1075 | u32 num_domains; |
1058 | u32 num_entries; | 1076 | u32 num_entries; |
1059 | u32 i; | 1077 | u32 i; |
1078 | u16 freq_mhz; | ||
1060 | int err; | 1079 | int err; |
1061 | int bit; | 1080 | int bit; |
1062 | 1081 | ||
@@ -1107,18 +1126,19 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g, | |||
1107 | 1126 | ||
1108 | switch (clk_info.clk_type) { | 1127 | switch (clk_info.clk_type) { |
1109 | case NVGPU_GPU_CLK_TYPE_TARGET: | 1128 | case NVGPU_GPU_CLK_TYPE_TARGET: |
1110 | err = nvgpu_clk_arb_get_session_target_hz(session, | 1129 | err = nvgpu_clk_arb_get_session_target_mhz(session, |
1111 | clk_info.clk_domain, &clk_info.freq_hz); | 1130 | clk_info.clk_domain, &freq_mhz); |
1112 | break; | 1131 | break; |
1113 | case NVGPU_GPU_CLK_TYPE_ACTUAL: | 1132 | case NVGPU_GPU_CLK_TYPE_ACTUAL: |
1114 | err = nvgpu_clk_arb_get_arbiter_actual_hz(g, | 1133 | err = nvgpu_clk_arb_get_arbiter_actual_mhz(g, |
1115 | clk_info.clk_domain, &clk_info.freq_hz); | 1134 | clk_info.clk_domain, &freq_mhz); |
1116 | break; | 1135 | break; |
1117 | case NVGPU_GPU_CLK_TYPE_EFFECTIVE: | 1136 | case NVGPU_GPU_CLK_TYPE_EFFECTIVE: |
1118 | err = nvgpu_clk_arb_get_arbiter_effective_hz(g, | 1137 | err = nvgpu_clk_arb_get_arbiter_effective_mhz(g, |
1119 | clk_info.clk_domain, &clk_info.freq_hz); | 1138 | clk_info.clk_domain, &freq_mhz); |
1120 | break; | 1139 | break; |
1121 | default: | 1140 | default: |
1141 | freq_mhz = 0; | ||
1122 | err = -EINVAL; | 1142 | err = -EINVAL; |
1123 | break; | 1143 | break; |
1124 | } | 1144 | } |
@@ -1126,6 +1146,7 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g, | |||
1126 | return err; | 1146 | return err; |
1127 | 1147 | ||
1128 | clk_info.flags = 0; | 1148 | clk_info.flags = 0; |
1149 | clk_info.freq_hz = MHZ_TO_HZ(freq_mhz); | ||
1129 | 1150 | ||
1130 | err = copy_to_user((void __user *)entry, &clk_info, | 1151 | err = copy_to_user((void __user *)entry, &clk_info, |
1131 | sizeof(clk_info)); | 1152 | sizeof(clk_info)); |