diff options
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/clk_gm20b.c | 121 |
1 files changed, 115 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c index adf5136a..b1d1af4d 100644 --- a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c | |||
@@ -43,6 +43,10 @@ | |||
43 | #define BOOT_GPU_UV 1000000 /* gpu rail boot voltage 1.0V */ | 43 | #define BOOT_GPU_UV 1000000 /* gpu rail boot voltage 1.0V */ |
44 | #define ADC_SLOPE_UV 10000 /* default ADC detection slope 10mV */ | 44 | #define ADC_SLOPE_UV 10000 /* default ADC detection slope 10mV */ |
45 | 45 | ||
46 | /* FIXME: need characterized safe margin constant or table, and minimum */ | ||
47 | #define DVFS_SAFE_MARGIN (2*38400) | ||
48 | #define DVFS_SAFE_MIN_FREQ (2*307200) | ||
49 | |||
46 | static struct pll_parms gpc_pll_params = { | 50 | static struct pll_parms gpc_pll_params = { |
47 | 128000, 2600000, /* freq */ | 51 | 128000, 2600000, /* freq */ |
48 | 1300000, 2600000, /* vco */ | 52 | 1300000, 2600000, /* vco */ |
@@ -222,7 +226,7 @@ found_match: | |||
222 | 226 | ||
223 | *target_freq = pll->freq; | 227 | *target_freq = pll->freq; |
224 | 228 | ||
225 | gk20a_dbg_clk("actual target freq %d MHz, M %d, N %d, PL %d(div%d)", | 229 | gk20a_dbg_clk("actual target freq %d kHz, M %d, N %d, PL %d(div%d)", |
226 | *target_freq, pll->M, pll->N, pll->PL, pl_to_div(pll->PL)); | 230 | *target_freq, pll->M, pll->N, pll->PL, pl_to_div(pll->PL)); |
227 | 231 | ||
228 | gk20a_dbg_fn("done"); | 232 | gk20a_dbg_fn("done"); |
@@ -743,7 +747,14 @@ pll_locked: | |||
743 | return 0; | 747 | return 0; |
744 | } | 748 | } |
745 | 749 | ||
746 | /* GPCPLL programming in legacy (non-DVFS) mode */ | 750 | /* |
751 | * Change GPCPLL frequency: | ||
752 | * - in legacy (non-DVFS) mode | ||
753 | * - in DVFS mode at constant DVFS detection settings, matching current/lower | ||
754 | * voltage; the same procedure can be used in this case, since maximum DVFS | ||
755 | * detection limit makes sure that PLL output remains under F/V curve when | ||
756 | * voltage increases arbitrary. | ||
757 | */ | ||
747 | static int clk_program_gpc_pll(struct gk20a *g, struct pll *gpll_new, | 758 | static int clk_program_gpc_pll(struct gk20a *g, struct pll *gpll_new, |
748 | int allow_slide) | 759 | int allow_slide) |
749 | { | 760 | { |
@@ -868,17 +879,115 @@ set_pldiv: | |||
868 | return clk_slide_gpc_pll(g, gpll_new); | 879 | return clk_slide_gpc_pll(g, gpll_new); |
869 | } | 880 | } |
870 | 881 | ||
871 | /* GPCPLL programming in DVFS mode */ | 882 | /* Find GPCPLL config safe at DVFS coefficient = 0, matching target frequency */ |
883 | static void clk_config_pll_safe_dvfs(struct gk20a *g, struct pll *gpll) | ||
884 | { | ||
885 | u32 nsafe, nmin; | ||
886 | |||
887 | if (gpll->freq > DVFS_SAFE_MIN_FREQ) | ||
888 | gpll->freq -= DVFS_SAFE_MARGIN; | ||
889 | |||
890 | nmin = DIV_ROUND_UP(gpll->M * gpc_pll_params.min_vco, gpll->clk_in); | ||
891 | nsafe = gpll->M * gpll->freq / gpll->clk_in; | ||
892 | |||
893 | /* | ||
894 | * If safe frequency is above VCOmin, it can be used in safe PLL config | ||
895 | * as is. Since safe frequency is below both old and new frequencies, | ||
896 | * in this case all three configurations have same post divider 1:1, and | ||
897 | * direct old=>safe=>new n-sliding will be used for transitions. | ||
898 | * | ||
899 | * Otherwise, if safe frequency is below VCO min, post-divider in safe | ||
900 | * configuration (and possibly in old and/or new configurations) is | ||
901 | * above 1:1, and each old=>safe and safe=>new transitions includes | ||
902 | * sliding to/from VCOmin, as well as divider changes. To avoid extra | ||
903 | * dynamic ramps from VCOmin during old=>safe transition and to VCOmin | ||
904 | * during safe=>new transition, select nmin as safe NDIV, and set safe | ||
905 | * post divider to assure PLL output is below safe frequency | ||
906 | */ | ||
907 | if (nsafe < nmin) { | ||
908 | gpll->PL = DIV_ROUND_UP(nmin * gpll->clk_in, | ||
909 | gpll->M * gpll->freq); | ||
910 | nsafe = nmin; | ||
911 | } | ||
912 | gpll->N = nsafe; | ||
913 | clk_config_dvfs_ndiv(gpll->dvfs.mv, gpll->N, &gpll->dvfs); | ||
914 | |||
915 | gk20a_dbg_clk("safe freq %d kHz, M %d, N %d, PL %d(div%d)", | ||
916 | gpll->freq, gpll->M, gpll->N, gpll->PL, pl_to_div(gpll->PL)); | ||
917 | } | ||
918 | |||
919 | /* Change GPCPLL frequency and DVFS detection settings in DVFS mode */ | ||
872 | static int clk_program_na_gpc_pll(struct gk20a *g, struct pll *gpll_new, | 920 | static int clk_program_na_gpc_pll(struct gk20a *g, struct pll *gpll_new, |
873 | int allow_slide) | 921 | int allow_slide) |
874 | { | 922 | { |
923 | int ret; | ||
924 | struct pll gpll_safe; | ||
925 | struct pll *gpll_old = &g->clk.gpc_pll_last; | ||
926 | |||
927 | BUG_ON(gpll_new->M != 1); /* the only MDIV in NA mode */ | ||
875 | clk_config_dvfs(g, gpll_new); | 928 | clk_config_dvfs(g, gpll_new); |
876 | 929 | ||
877 | if (!gpll_new->enabled) | 930 | /* |
931 | * In cases below no intermediate steps in PLL DVFS configuration are | ||
932 | * necessary because either | ||
933 | * - PLL DVFS will be configured under bypass directly to target, or | ||
934 | * - voltage is not changing, so DVFS detection settings are the same | ||
935 | */ | ||
936 | if (!allow_slide || !gpll_new->enabled || | ||
937 | (gpll_old->dvfs.mv == gpll_new->dvfs.mv)) | ||
878 | return clk_program_gpc_pll(g, gpll_new, allow_slide); | 938 | return clk_program_gpc_pll(g, gpll_new, allow_slide); |
879 | 939 | ||
880 | /* always under bypass, for now */ | 940 | /* |
881 | return clk_program_gpc_pll(g, gpll_new, 0); | 941 | * Interim step for changing DVFS detection settings: low enough |
942 | * frequency to be safe at at DVFS coeff = 0. | ||
943 | * | ||
944 | * 1. If voltage is increasing: | ||
945 | * - safe frequency target matches the lowest - old - frequency | ||
946 | * - DVFS settings are still old | ||
947 | * - Voltage already increased to new level by tegra DVFS, but maximum | ||
948 | * detection limit assures PLL output remains under F/V curve | ||
949 | * | ||
950 | * 2. If voltage is decreasing: | ||
951 | * - safe frequency target matches the lowest - new - frequency | ||
952 | * - DVFS settings are still old | ||
953 | * - Voltage is also old, it will be lowered by tegra DVFS afterwards | ||
954 | * | ||
955 | * Interim step can be skipped if old frequency is below safe minimum, | ||
956 | * i.e., it is low enough to be safe at any voltage in operating range | ||
957 | * with zero DVFS coefficient. | ||
958 | */ | ||
959 | if (gpll_old->freq > DVFS_SAFE_MIN_FREQ) { | ||
960 | if (gpll_old->dvfs.mv < gpll_new->dvfs.mv) { | ||
961 | gpll_safe = *gpll_old; | ||
962 | gpll_safe.dvfs.mv = gpll_new->dvfs.mv; | ||
963 | } else { | ||
964 | gpll_safe = *gpll_new; | ||
965 | gpll_safe.dvfs = gpll_old->dvfs; | ||
966 | } | ||
967 | clk_config_pll_safe_dvfs(g, &gpll_safe); | ||
968 | |||
969 | ret = clk_program_gpc_pll(g, &gpll_safe, 1); | ||
970 | if (ret) { | ||
971 | gk20a_err(dev_from_gk20a(g), "Safe dvfs program fail\n"); | ||
972 | return ret; | ||
973 | } | ||
974 | } | ||
975 | |||
976 | /* | ||
977 | * DVFS detection settings transition: | ||
978 | * - Set DVFS coefficient zero (safe, since already at frequency safe | ||
979 | * at DVFS coeff = 0 for the lowest of the old/new end-points) | ||
980 | * - Set calibration level to new voltage (safe, since DVFS coeff = 0) | ||
981 | * - Set DVFS coefficient to match new voltage (safe, since already at | ||
982 | * frequency safe at DVFS coeff = 0 for the lowest of the old/new | ||
983 | * end-points. | ||
984 | */ | ||
985 | clk_set_dfs_coeff(g, 0); | ||
986 | clk_set_dfs_ext_cal(g, gpll_new->dvfs.dfs_ext_cal); | ||
987 | clk_set_dfs_coeff(g, gpll_new->dvfs.dfs_coeff); | ||
988 | |||
989 | /* Finally set target rate (with DVFS detection settings already new) */ | ||
990 | return clk_program_gpc_pll(g, gpll_new, 1); | ||
882 | } | 991 | } |
883 | 992 | ||
884 | static int clk_disable_gpcpll(struct gk20a *g, int allow_slide) | 993 | static int clk_disable_gpcpll(struct gk20a *g, int allow_slide) |