mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 09:57:08 +03:00
gpu: nvgpu: Combine delays with GM20B parameters
Added delays definitions to GPCPLL parameters structure: - locking timeout delay (applied to locking in fixed frequency mode and to PLL dynamic ramp in any mode) - lock delay for GPCPLL NA mode - IDDQ exit delay in any mode Specified delay parameters for GM20B PLL, and used this data instead of hard-coded numbers. Change-Id: I63ce0abc9ee900c36ec34b8641513db3cbb6f7d5 Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/732094 Reviewed-by: Seshendra Gadagottu <sgadagottu@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
This commit is contained in:
@@ -25,8 +25,8 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum gpc_pll_mode {
|
enum gpc_pll_mode {
|
||||||
GPC_PLL_MODE_F = 0,
|
GPC_PLL_MODE_F = 0, /* fixed frequency mode a.k.a legacy mode */
|
||||||
GPC_PLL_MODE_DVFS,
|
GPC_PLL_MODE_DVFS, /* DVFS mode a.k.a NA mode */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct na_dvfs {
|
struct na_dvfs {
|
||||||
@@ -62,6 +62,16 @@ struct pll_parms {
|
|||||||
int coeff_slope, coeff_offs; /* coeff = slope * V + offs */
|
int coeff_slope, coeff_offs; /* coeff = slope * V + offs */
|
||||||
int uvdet_slope, uvdet_offs; /* uV = slope * det + offs */
|
int uvdet_slope, uvdet_offs; /* uV = slope * det + offs */
|
||||||
u32 vco_ctrl;
|
u32 vco_ctrl;
|
||||||
|
/*
|
||||||
|
* Timing parameters in us. Lock timeout is applied to locking in fixed
|
||||||
|
* frequency mode and to dynamic ramp in any mode; does not affect lock
|
||||||
|
* latency, since lock/ramp done status bit is polled. NA mode lock and
|
||||||
|
* and IDDQ exit delays set the time of the respective opertaions with
|
||||||
|
* no status polling.
|
||||||
|
*/
|
||||||
|
u32 lock_timeout;
|
||||||
|
u32 na_lock_delay;
|
||||||
|
u32 iddq_exit_delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clk_gk20a {
|
struct clk_gk20a {
|
||||||
@@ -70,7 +80,6 @@ struct clk_gk20a {
|
|||||||
struct pll gpc_pll;
|
struct pll gpc_pll;
|
||||||
struct pll gpc_pll_last;
|
struct pll gpc_pll_last;
|
||||||
u32 pll_delay; /* default PLL settle time */
|
u32 pll_delay; /* default PLL settle time */
|
||||||
u32 na_pll_delay; /* default PLL settle time in NA mode */
|
|
||||||
struct mutex clk_mutex;
|
struct mutex clk_mutex;
|
||||||
bool sw_ready;
|
bool sw_ready;
|
||||||
bool clk_hw_on;
|
bool clk_hw_on;
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ static struct pll_parms gpc_pll_params = {
|
|||||||
-165230, 214007, /* DFS_COEFF */
|
-165230, 214007, /* DFS_COEFF */
|
||||||
0, 0, /* ADC char coeff - to be read from fuses */
|
0, 0, /* ADC char coeff - to be read from fuses */
|
||||||
0x7 << 3, /* vco control in NA mode */
|
0x7 << 3, /* vco control in NA mode */
|
||||||
|
500, /* Locking and ramping timeout */
|
||||||
|
40, /* Lock delay in NA mode */
|
||||||
|
5, /* IDDQ mode exit delay */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
@@ -411,7 +414,7 @@ static void clk_setup_dvfs_detection(struct gk20a *g, struct pll *gpll)
|
|||||||
static int clk_enbale_pll_dvfs(struct gk20a *g)
|
static int clk_enbale_pll_dvfs(struct gk20a *g)
|
||||||
{
|
{
|
||||||
u32 data;
|
u32 data;
|
||||||
int delay = 5; /* use for iddq exit delay & calib timeout */
|
int delay = gpc_pll_params.iddq_exit_delay; /* iddq & calib delay */
|
||||||
struct pll_parms *p = &gpc_pll_params;
|
struct pll_parms *p = &gpc_pll_params;
|
||||||
bool calibrated = p->uvdet_slope && p->uvdet_offs;
|
bool calibrated = p->uvdet_slope && p->uvdet_offs;
|
||||||
|
|
||||||
@@ -527,7 +530,7 @@ static int clk_slide_gpc_pll(struct gk20a *g, struct pll *gpll)
|
|||||||
{
|
{
|
||||||
u32 data, coeff;
|
u32 data, coeff;
|
||||||
u32 nold, sdm_old;
|
u32 nold, sdm_old;
|
||||||
int ramp_timeout = 500;
|
int ramp_timeout = gpc_pll_params.lock_timeout;
|
||||||
|
|
||||||
/* get old coefficients */
|
/* get old coefficients */
|
||||||
coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r());
|
coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r());
|
||||||
@@ -666,7 +669,7 @@ static int clk_lock_gpc_pll_under_bypass(struct gk20a *g, struct pll *gpll)
|
|||||||
trim_sys_gpcpll_cfg_iddq_power_on_v());
|
trim_sys_gpcpll_cfg_iddq_power_on_v());
|
||||||
gk20a_writel(g, trim_sys_gpcpll_cfg_r(), cfg);
|
gk20a_writel(g, trim_sys_gpcpll_cfg_r(), cfg);
|
||||||
gk20a_readl(g, trim_sys_gpcpll_cfg_r());
|
gk20a_readl(g, trim_sys_gpcpll_cfg_r());
|
||||||
udelay(5);
|
udelay(gpc_pll_params.iddq_exit_delay);
|
||||||
} else {
|
} else {
|
||||||
/* clear SYNC_MODE before disabling PLL */
|
/* clear SYNC_MODE before disabling PLL */
|
||||||
cfg = set_field(cfg, trim_sys_gpcpll_cfg_sync_mode_m(),
|
cfg = set_field(cfg, trim_sys_gpcpll_cfg_sync_mode_m(),
|
||||||
@@ -710,7 +713,7 @@ static int clk_lock_gpc_pll_under_bypass(struct gk20a *g, struct pll *gpll)
|
|||||||
/* just delay in DVFS mode (lock cannot be used) */
|
/* just delay in DVFS mode (lock cannot be used) */
|
||||||
if (gpll->mode == GPC_PLL_MODE_DVFS) {
|
if (gpll->mode == GPC_PLL_MODE_DVFS) {
|
||||||
gk20a_readl(g, trim_sys_gpcpll_cfg_r());
|
gk20a_readl(g, trim_sys_gpcpll_cfg_r());
|
||||||
udelay(g->clk.na_pll_delay);
|
udelay(gpc_pll_params.na_lock_delay);
|
||||||
gk20a_dbg_clk("NA config_pll under bypass: %u (%u) kHz %d mV",
|
gk20a_dbg_clk("NA config_pll under bypass: %u (%u) kHz %d mV",
|
||||||
gpll->freq, gpll->freq / 2,
|
gpll->freq, gpll->freq / 2,
|
||||||
(trim_sys_gpcpll_cfg3_dfs_testout_v(
|
(trim_sys_gpcpll_cfg3_dfs_testout_v(
|
||||||
@@ -730,7 +733,7 @@ static int clk_lock_gpc_pll_under_bypass(struct gk20a *g, struct pll *gpll)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* wait pll lock */
|
/* wait pll lock */
|
||||||
timeout = g->clk.pll_delay + 1;
|
timeout = gpc_pll_params.lock_timeout + 1;
|
||||||
do {
|
do {
|
||||||
udelay(1);
|
udelay(1);
|
||||||
cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
|
cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
|
||||||
@@ -1088,15 +1091,6 @@ static int gm20b_init_clk_setup_sw(struct gk20a *g)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Locking time in both legacy and DVFS mode is 40us. However, in legacy
|
|
||||||
* mode we rely on lock detection signal, and delay is just timeout
|
|
||||||
* limit, so we can afford set it longer. In DVFS mode each lock inserts
|
|
||||||
* specified delay, so it should be set as short as h/w allows.
|
|
||||||
*/
|
|
||||||
clk->pll_delay = 300; /* usec */
|
|
||||||
clk->na_pll_delay = 40; /* usec*/
|
|
||||||
|
|
||||||
clk->gpc_pll.id = GK20A_GPC_PLL;
|
clk->gpc_pll.id = GK20A_GPC_PLL;
|
||||||
clk->gpc_pll.clk_in = clk_get_rate(ref) / KHZ;
|
clk->gpc_pll.clk_in = clk_get_rate(ref) / KHZ;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user