mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: Use 1kHz resolution for GPCPLL programming
Used 1kHz resolution (instead of 1 MHz) for GPCPLL programming: limits specifications, calculating GPCPLL settings, storing target frequency values, and proving output from debug monitor. Updated comments in clock header to properly reflect frequency units. Bug 1450787 Change-Id: Ica58f794b82522288f2883c40626d82dbd794902 Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/437943 Reviewed-by: Seshendra Gadagottu <sgadagottu@nvidia.com> Tested-by: Seshendra Gadagottu <sgadagottu@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
This commit is contained in:
@@ -34,12 +34,12 @@
|
|||||||
|
|
||||||
/* from vbios PLL info table */
|
/* from vbios PLL info table */
|
||||||
struct pll_parms gpc_pll_params = {
|
struct pll_parms gpc_pll_params = {
|
||||||
144, 2064, /* freq */
|
144000, 2064000, /* freq */
|
||||||
1000, 2064, /* vco */
|
1000000, 2064000, /* vco */
|
||||||
12, 38, /* u */
|
12000, 38000, /* u */
|
||||||
1, 255, /* M */
|
1, 255, /* M */
|
||||||
8, 255, /* N */
|
8, 255, /* N */
|
||||||
1, 32, /* PL */
|
1, 32, /* PL */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int num_gpu_cooling_freq;
|
static int num_gpu_cooling_freq;
|
||||||
@@ -467,7 +467,7 @@ static int gk20a_init_clk_setup_sw(struct gk20a *g)
|
|||||||
clk->pll_delay = 300; /* usec */
|
clk->pll_delay = 300; /* usec */
|
||||||
|
|
||||||
clk->gpc_pll.id = GK20A_GPC_PLL;
|
clk->gpc_pll.id = GK20A_GPC_PLL;
|
||||||
clk->gpc_pll.clk_in = ref_rate / 1000000; /* MHz */
|
clk->gpc_pll.clk_in = ref_rate / KHZ;
|
||||||
|
|
||||||
/* Decide initial frequency */
|
/* Decide initial frequency */
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
@@ -777,7 +777,7 @@ static int pll_reg_show(struct seq_file *s, void *data)
|
|||||||
pl = trim_sys_gpcpll_coeff_pldiv_v(reg);
|
pl = trim_sys_gpcpll_coeff_pldiv_v(reg);
|
||||||
f = g->clk.gpc_pll.clk_in * n / (m * pl_to_div[pl]);
|
f = g->clk.gpc_pll.clk_in * n / (m * pl_to_div[pl]);
|
||||||
seq_printf(s, "coef = 0x%x : m = %u : n = %u : pl = %u", reg, m, n, pl);
|
seq_printf(s, "coef = 0x%x : m = %u : n = %u : pl = %u", reg, m, n, pl);
|
||||||
seq_printf(s, " : pll_f(gpu_f) = %u(%u) MHz\n", f, f/2);
|
seq_printf(s, " : pll_f(gpu_f) = %u(%u) kHz\n", f, f/2);
|
||||||
mutex_unlock(&g->clk.clk_mutex);
|
mutex_unlock(&g->clk.clk_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -801,7 +801,7 @@ static int monitor_get(void *data, u64 *val)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
u32 ncycle = 100; /* count GPCCLK for ncycle of clkin */
|
u32 ncycle = 100; /* count GPCCLK for ncycle of clkin */
|
||||||
u32 clkin = clk->gpc_pll.clk_in;
|
u64 freq = clk->gpc_pll.clk_in;
|
||||||
u32 count1, count2;
|
u32 count1, count2;
|
||||||
|
|
||||||
err = gk20a_busy(g->dev);
|
err = gk20a_busy(g->dev);
|
||||||
@@ -824,7 +824,10 @@ static int monitor_get(void *data, u64 *val)
|
|||||||
count1 = gk20a_readl(g, trim_gpc_clk_cntr_ncgpcclk_cnt_r(0));
|
count1 = gk20a_readl(g, trim_gpc_clk_cntr_ncgpcclk_cnt_r(0));
|
||||||
udelay(100);
|
udelay(100);
|
||||||
count2 = gk20a_readl(g, trim_gpc_clk_cntr_ncgpcclk_cnt_r(0));
|
count2 = gk20a_readl(g, trim_gpc_clk_cntr_ncgpcclk_cnt_r(0));
|
||||||
*val = (u64)(trim_gpc_clk_cntr_ncgpcclk_cnt_value_v(count2) * clkin / ncycle);
|
freq *= trim_gpc_clk_cntr_ncgpcclk_cnt_value_v(count2);
|
||||||
|
do_div(freq, ncycle);
|
||||||
|
*val = freq;
|
||||||
|
|
||||||
gk20a_idle(g->dev);
|
gk20a_idle(g->dev);
|
||||||
|
|
||||||
if (count1 != count2)
|
if (count1 != count2)
|
||||||
|
|||||||
@@ -31,18 +31,18 @@ enum {
|
|||||||
|
|
||||||
struct pll {
|
struct pll {
|
||||||
u32 id;
|
u32 id;
|
||||||
u32 clk_in; /* MHz */
|
u32 clk_in; /* KHz */
|
||||||
u32 M;
|
u32 M;
|
||||||
u32 N;
|
u32 N;
|
||||||
u32 PL;
|
u32 PL;
|
||||||
u32 freq; /* MHz */
|
u32 freq; /* KHz */
|
||||||
bool enabled;
|
bool enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pll_parms {
|
struct pll_parms {
|
||||||
u32 min_freq, max_freq; /* MHz */
|
u32 min_freq, max_freq; /* KHz */
|
||||||
u32 min_vco, max_vco; /* MHz */
|
u32 min_vco, max_vco; /* KHz */
|
||||||
u32 min_u, max_u; /* MHz */
|
u32 min_u, max_u; /* KHz */
|
||||||
u32 min_M, max_M;
|
u32 min_M, max_M;
|
||||||
u32 min_N, max_N;
|
u32 min_N, max_N;
|
||||||
u32 min_PL, max_PL;
|
u32 min_PL, max_PL;
|
||||||
@@ -60,7 +60,7 @@ struct clk_gk20a {
|
|||||||
|
|
||||||
struct gpufreq_table_data {
|
struct gpufreq_table_data {
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
unsigned int frequency; /* MHz */
|
unsigned int frequency; /* Hz */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gpufreq_table_data *tegra_gpufreq_table_get(void);
|
struct gpufreq_table_data *tegra_gpufreq_table_get(void);
|
||||||
@@ -82,13 +82,13 @@ extern struct pll_parms gpc_pll_params;
|
|||||||
|
|
||||||
static inline unsigned long rate_gpc2clk_to_gpu(unsigned long rate)
|
static inline unsigned long rate_gpc2clk_to_gpu(unsigned long rate)
|
||||||
{
|
{
|
||||||
/* convert the MHz gpc2clk frequency to Hz gpcpll frequency */
|
/* convert the kHz gpc2clk frequency to Hz gpcpll frequency */
|
||||||
return (rate * MHZ) / 2;
|
return (rate * KHZ) / 2;
|
||||||
}
|
}
|
||||||
static inline unsigned long rate_gpu_to_gpc2clk(unsigned long rate)
|
static inline unsigned long rate_gpu_to_gpc2clk(unsigned long rate)
|
||||||
{
|
{
|
||||||
/* convert the Hz gpcpll frequency to MHz gpc2clk frequency */
|
/* convert the Hz gpcpll frequency to kHz gpc2clk frequency */
|
||||||
return (rate * 2) / MHZ;
|
return (rate * 2) / KHZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _NVHOST_CLK_GK20A_H_ */
|
#endif /* _NVHOST_CLK_GK20A_H_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user