summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2014-09-21 00:28:51 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:11:28 -0400
commit3a81ed7e979343df35d65279fb101cbb5f0ccfc7 (patch)
tree1302b025e5d2668503eccb47c915f5982eaa20bd /drivers/gpu/nvgpu/gm20b/clk_gm20b.c
parent270029a760303443caaf2deb2c74cad67bbb7709 (diff)
gpu: nvgpu: Change GPCPLL NA rate in flight
Added support for GM20b GPCPLL frequency change in NA mode outside of bypass. In this case the respective PLL DVFS detection settings are updated in flight. The implemented algorithm relies on characterization providing two frequency limits at the same voltage: max frequency on the F/V curve (Fmax@V) in NA mode with characterized DVFS coefficient, and safe frequency under the curve when DVFS coefficient is zero (Fsafe@V, which is effectively the same as Fmax@V in legacy/non-DVFS mode). Transition between two Fmax@V points on the curve includes: - Lowering frequency to Fsafe@V for the minimum V of the transition end-points - Setting DVFS coefficient to zero - Changing DVFS calibration point to the new voltage - Setting DVFS coefficient characterized for the new voltage - Setting final target frequency Note that voltage is changed by Tegra SoC DVFS before (when voltage increases), or after (whet voltage decreases) the above procedure. This commit kept NA mode disabled. Bug 1555318 Change-Id: Ib5620aaa113dc1caa69ecd402d9c6f68e39c472c Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/501042 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b/clk_gm20b.c')
-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)