summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gm20b/clk_gm20b.c121
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
46static struct pll_parms gpc_pll_params = { 50static 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 */
747static int clk_program_gpc_pll(struct gk20a *g, struct pll *gpll_new, 758static 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 */
883static 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 */
872static int clk_program_na_gpc_pll(struct gk20a *g, struct pll *gpll_new, 920static 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
884static int clk_disable_gpcpll(struct gk20a *g, int allow_slide) 993static int clk_disable_gpcpll(struct gk20a *g, int allow_slide)