summaryrefslogtreecommitdiff
path: root/drivers/clk/tegra
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-08-07 10:36:12 +0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-08-07 10:36:12 +0400
commit5e2aa2ed08e2e280121dc7cf5609c87d464f12ef (patch)
treeca7d7b1480285e3b617fecc5b41f0ce150a82c32 /drivers/clk/tegra
parentf62d14a8072b9756db36ba394e2b267470a40240 (diff)
parentfc8104bc5a3f6f49d79f45f2706f79f77a9fb2ae (diff)
downloadlinux-5e2aa2ed08e2e280121dc7cf5609c87d464f12ef.tar.xz
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.17.
Diffstat (limited to 'drivers/clk/tegra')
-rw-r--r--drivers/clk/tegra/clk-id.h1
-rw-r--r--drivers/clk/tegra/clk-pll.c99
-rw-r--r--drivers/clk/tegra/clk-tegra-periph.c10
-rw-r--r--drivers/clk/tegra/clk-tegra114.c22
-rw-r--r--drivers/clk/tegra/clk-tegra124.c21
5 files changed, 108 insertions, 45 deletions
diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h
index c39613c519af..0011d547a9f7 100644
--- a/drivers/clk/tegra/clk-id.h
+++ b/drivers/clk/tegra/clk-id.h
@@ -233,6 +233,7 @@ enum clk_id {
tegra_clk_xusb_hs_src,
tegra_clk_xusb_ss,
tegra_clk_xusb_ss_src,
+ tegra_clk_xusb_ss_div2,
tegra_clk_max,
};
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 0d20241e0770..637b62ccc91e 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -58,9 +58,9 @@
#define PLLDU_LFCON_SET_DIVN 600
#define PLLE_BASE_DIVCML_SHIFT 24
-#define PLLE_BASE_DIVCML_WIDTH 4
+#define PLLE_BASE_DIVCML_MASK 0xf
#define PLLE_BASE_DIVP_SHIFT 16
-#define PLLE_BASE_DIVP_WIDTH 7
+#define PLLE_BASE_DIVP_WIDTH 6
#define PLLE_BASE_DIVN_SHIFT 8
#define PLLE_BASE_DIVN_WIDTH 8
#define PLLE_BASE_DIVM_SHIFT 0
@@ -96,10 +96,20 @@
(PLLE_SS_MAX_VAL | PLLE_SS_INC_VAL | PLLE_SS_INCINTRV_VAL)
#define PLLE_AUX_PLLP_SEL BIT(2)
+#define PLLE_AUX_USE_LOCKDET BIT(3)
#define PLLE_AUX_ENABLE_SWCTL BIT(4)
+#define PLLE_AUX_SS_SWCTL BIT(6)
#define PLLE_AUX_SEQ_ENABLE BIT(24)
+#define PLLE_AUX_SEQ_START_STATE BIT(25)
#define PLLE_AUX_PLLRE_SEL BIT(28)
+#define XUSBIO_PLL_CFG0 0x51c
+#define XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0)
+#define XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL BIT(2)
+#define XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET BIT(6)
+#define XUSBIO_PLL_CFG0_SEQ_ENABLE BIT(24)
+#define XUSBIO_PLL_CFG0_SEQ_START_STATE BIT(25)
+
#define PLLE_MISC_PLLE_PTS BIT(8)
#define PLLE_MISC_IDDQ_SW_VALUE BIT(13)
#define PLLE_MISC_IDDQ_SW_CTRL BIT(14)
@@ -183,6 +193,14 @@
#define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\
mask(p->params->div_nmp->divp_width))
+#define divm_shift(p) (p)->params->div_nmp->divm_shift
+#define divn_shift(p) (p)->params->div_nmp->divn_shift
+#define divp_shift(p) (p)->params->div_nmp->divp_shift
+
+#define divm_mask_shifted(p) (divm_mask(p) << divm_shift(p))
+#define divn_mask_shifted(p) (divn_mask(p) << divn_shift(p))
+#define divp_mask_shifted(p) (divp_mask(p) << divp_shift(p))
+
#define divm_max(p) (divm_mask(p))
#define divn_max(p) (divn_mask(p))
#define divp_max(p) (1 << (divp_mask(p)))
@@ -476,13 +494,12 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll,
} else {
val = pll_readl_base(pll);
- val &= ~((divm_mask(pll) << div_nmp->divm_shift) |
- (divn_mask(pll) << div_nmp->divn_shift) |
- (divp_mask(pll) << div_nmp->divp_shift));
+ val &= ~(divm_mask_shifted(pll) | divn_mask_shifted(pll) |
+ divp_mask_shifted(pll));
- val |= ((cfg->m << div_nmp->divm_shift) |
- (cfg->n << div_nmp->divn_shift) |
- (cfg->p << div_nmp->divp_shift));
+ val |= (cfg->m << divm_shift(pll)) |
+ (cfg->n << divn_shift(pll)) |
+ (cfg->p << divp_shift(pll));
pll_writel_base(val, pll);
}
@@ -730,11 +747,12 @@ static int clk_plle_enable(struct clk_hw *hw)
if (pll->params->flags & TEGRA_PLLE_CONFIGURE) {
/* configure dividers */
val = pll_readl_base(pll);
- val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
- val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
- val |= sel.m << pll->params->div_nmp->divm_shift;
- val |= sel.n << pll->params->div_nmp->divn_shift;
- val |= sel.p << pll->params->div_nmp->divp_shift;
+ val &= ~(divp_mask_shifted(pll) | divn_mask_shifted(pll) |
+ divm_mask_shifted(pll));
+ val &= ~(PLLE_BASE_DIVCML_MASK << PLLE_BASE_DIVCML_SHIFT);
+ val |= sel.m << divm_shift(pll);
+ val |= sel.n << divn_shift(pll);
+ val |= sel.p << divp_shift(pll);
val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
pll_writel_base(val, pll);
}
@@ -745,10 +763,11 @@ static int clk_plle_enable(struct clk_hw *hw)
pll_writel_misc(val, pll);
val = readl(pll->clk_base + PLLE_SS_CTRL);
+ val &= ~PLLE_SS_COEFFICIENTS_MASK;
val |= PLLE_SS_DISABLE;
writel(val, pll->clk_base + PLLE_SS_CTRL);
- val |= pll_readl_base(pll);
+ val = pll_readl_base(pll);
val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE);
pll_writel_base(val, pll);
@@ -1292,10 +1311,11 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw)
pll_writel(val, PLLE_SS_CTRL, pll);
val = pll_readl_base(pll);
- val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
- val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
- val |= sel.m << pll->params->div_nmp->divm_shift;
- val |= sel.n << pll->params->div_nmp->divn_shift;
+ val &= ~(divp_mask_shifted(pll) | divn_mask_shifted(pll) |
+ divm_mask_shifted(pll));
+ val &= ~(PLLE_BASE_DIVCML_MASK << PLLE_BASE_DIVCML_SHIFT);
+ val |= sel.m << divm_shift(pll);
+ val |= sel.n << divn_shift(pll);
val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
pll_writel_base(val, pll);
udelay(1);
@@ -1318,7 +1338,28 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw)
pll_writel(val, PLLE_SS_CTRL, pll);
udelay(1);
- /* TODO: enable hw control of xusb brick pll */
+ /* Enable hw control of xusb brick pll */
+ val = pll_readl_misc(pll);
+ val &= ~PLLE_MISC_IDDQ_SW_CTRL;
+ pll_writel_misc(val, pll);
+
+ val = pll_readl(pll->params->aux_reg, pll);
+ val |= (PLLE_AUX_USE_LOCKDET | PLLE_AUX_SEQ_START_STATE);
+ val &= ~(PLLE_AUX_ENABLE_SWCTL | PLLE_AUX_SS_SWCTL);
+ pll_writel(val, pll->params->aux_reg, pll);
+ udelay(1);
+ val |= PLLE_AUX_SEQ_ENABLE;
+ pll_writel(val, pll->params->aux_reg, pll);
+
+ val = pll_readl(XUSBIO_PLL_CFG0, pll);
+ val |= (XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET |
+ XUSBIO_PLL_CFG0_SEQ_START_STATE);
+ val &= ~(XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL |
+ XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL);
+ pll_writel(val, XUSBIO_PLL_CFG0, pll);
+ udelay(1);
+ val |= XUSBIO_PLL_CFG0_SEQ_ENABLE;
+ pll_writel(val, XUSBIO_PLL_CFG0, pll);
out:
if (pll->lock)
@@ -1410,6 +1451,15 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
return clk;
}
+static struct div_nmp pll_e_nmp = {
+ .divn_shift = PLLE_BASE_DIVN_SHIFT,
+ .divn_width = PLLE_BASE_DIVN_WIDTH,
+ .divm_shift = PLLE_BASE_DIVM_SHIFT,
+ .divm_width = PLLE_BASE_DIVM_WIDTH,
+ .divp_shift = PLLE_BASE_DIVP_SHIFT,
+ .divp_width = PLLE_BASE_DIVP_WIDTH,
+};
+
struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
void __iomem *clk_base, void __iomem *pmc,
unsigned long flags, struct tegra_clk_pll_params *pll_params,
@@ -1420,6 +1470,10 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
pll_params->flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS;
pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+
+ if (!pll_params->div_nmp)
+ pll_params->div_nmp = &pll_e_nmp;
+
pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -1557,9 +1611,8 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
int m;
m = _pll_fixed_mdiv(pll_params, parent_rate);
- val = m << PLL_BASE_DIVM_SHIFT;
- val |= (pll_params->vco_min / parent_rate)
- << PLL_BASE_DIVN_SHIFT;
+ val = m << divm_shift(pll);
+ val |= (pll_params->vco_min / parent_rate) << divn_shift(pll);
pll_writel_base(val, pll);
}
@@ -1718,7 +1771,7 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
"pll_re_vco");
} else {
val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL);
- pll_writel(val, pll_params->aux_reg, pll);
+ pll_writel(val_aux, pll_params->aux_reg, pll);
}
clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c
index 1fa5c3f33b20..adf6b814b5bc 100644
--- a/drivers/clk/tegra/clk-tegra-periph.c
+++ b/drivers/clk/tegra/clk-tegra-periph.c
@@ -329,7 +329,9 @@ static u32 mux_clkm_pllp_pllc_pllre_idx[] = {
static const char *mux_clkm_48M_pllp_480M[] = {
"clk_m", "pll_u_48M", "pll_p", "pll_u_480M"
};
-#define mux_clkm_48M_pllp_480M_idx NULL
+static u32 mux_clkm_48M_pllp_480M_idx[] = {
+ [0] = 0, [1] = 2, [2] = 4, [3] = 6,
+};
static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = {
"clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref"
@@ -338,6 +340,11 @@ static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = {
[0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7,
};
+static const char *mux_ss_60M[] = {
+ "xusb_ss_div2", "pll_u_60M"
+};
+#define mux_ss_60M_idx NULL
+
static const char *mux_d_audio_clk[] = {
"pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync",
"i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync",
@@ -499,6 +506,7 @@ static struct tegra_periph_init_data periph_clks[] = {
XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_falcon_src),
XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_fs_src),
XUSB("xusb_ss_src", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_ss_src),
+ NODIV("xusb_hs_src", mux_ss_60M, CLK_SOURCE_XUSB_SS_SRC, 25, MASK(1), 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_hs_src, NULL),
XUSB("xusb_dev_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_dev_src),
};
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index 80431f0fb268..b9c8ba258ef0 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -142,7 +142,6 @@
#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0)
#define CLK_SOURCE_CSITE 0x1d4
-#define CLK_SOURCE_XUSB_SS_SRC 0x610
#define CLK_SOURCE_EMC 0x19c
/* PLLM override registers */
@@ -834,6 +833,7 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = {
[tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA114_CLK_XUSB_FALCON_SRC, .present = true },
[tegra_clk_xusb_fs_src] = { .dt_id = TEGRA114_CLK_XUSB_FS_SRC, .present = true },
[tegra_clk_xusb_ss_src] = { .dt_id = TEGRA114_CLK_XUSB_SS_SRC, .present = true },
+ [tegra_clk_xusb_ss_div2] = { .dt_id = TEGRA114_CLK_XUSB_SS_DIV2, .present = true},
[tegra_clk_xusb_dev_src] = { .dt_id = TEGRA114_CLK_XUSB_DEV_SRC, .present = true },
[tegra_clk_xusb_dev] = { .dt_id = TEGRA114_CLK_XUSB_DEV, .present = true },
[tegra_clk_xusb_hs_src] = { .dt_id = TEGRA114_CLK_XUSB_HS_SRC, .present = true },
@@ -1182,16 +1182,11 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base,
void __iomem *pmc_base)
{
struct clk *clk;
- u32 val;
-
- /* xusb_hs_src */
- val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC);
- val |= BIT(25); /* always select PLLU_60M */
- writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC);
- clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0,
- 1, 1);
- clks[TEGRA114_CLK_XUSB_HS_SRC] = clk;
+ /* xusb_ss_div2 */
+ clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0,
+ 1, 2);
+ clks[TEGRA114_CLK_XUSB_SS_DIV2] = clk;
/* dsia mux */
clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0,
@@ -1301,7 +1296,12 @@ static struct tegra_clk_init_table init_table[] __initdata = {
{TEGRA114_CLK_GR3D, TEGRA114_CLK_PLL_C2, 300000000, 0},
{TEGRA114_CLK_DSIALP, TEGRA114_CLK_PLL_P, 68000000, 0},
{TEGRA114_CLK_DSIBLP, TEGRA114_CLK_PLL_P, 68000000, 0},
-
+ {TEGRA114_CLK_PLL_RE_VCO, TEGRA114_CLK_CLK_MAX, 612000000, 0},
+ {TEGRA114_CLK_XUSB_SS_SRC, TEGRA114_CLK_PLL_RE_OUT, 122400000, 0},
+ {TEGRA114_CLK_XUSB_FS_SRC, TEGRA114_CLK_PLL_U_48M, 48000000, 0},
+ {TEGRA114_CLK_XUSB_HS_SRC, TEGRA114_CLK_XUSB_SS_DIV2, 61200000, 0},
+ {TEGRA114_CLK_XUSB_FALCON_SRC, TEGRA114_CLK_PLL_P, 204000000, 0},
+ {TEGRA114_CLK_XUSB_HOST_SRC, TEGRA114_CLK_PLL_P, 102000000, 0},
/* This MUST be the last entry. */
{TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0},
};
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index cc37c342c4cb..80efe51fdcdf 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -30,7 +30,6 @@
#define CLK_SOURCE_CSITE 0x1d4
#define CLK_SOURCE_EMC 0x19c
-#define CLK_SOURCE_XUSB_SS_SRC 0x610
#define PLLC_BASE 0x80
#define PLLC_OUT 0x84
@@ -925,6 +924,7 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = {
[tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA124_CLK_XUSB_FALCON_SRC, .present = true },
[tegra_clk_xusb_fs_src] = { .dt_id = TEGRA124_CLK_XUSB_FS_SRC, .present = true },
[tegra_clk_xusb_ss_src] = { .dt_id = TEGRA124_CLK_XUSB_SS_SRC, .present = true },
+ [tegra_clk_xusb_ss_div2] = { .dt_id = TEGRA124_CLK_XUSB_SS_DIV2, .present = true },
[tegra_clk_xusb_dev_src] = { .dt_id = TEGRA124_CLK_XUSB_DEV_SRC, .present = true },
[tegra_clk_xusb_dev] = { .dt_id = TEGRA124_CLK_XUSB_DEV, .present = true },
[tegra_clk_xusb_hs_src] = { .dt_id = TEGRA124_CLK_XUSB_HS_SRC, .present = true },
@@ -1105,16 +1105,11 @@ static __init void tegra124_periph_clk_init(void __iomem *clk_base,
void __iomem *pmc_base)
{
struct clk *clk;
- u32 val;
-
- /* xusb_hs_src */
- val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC);
- val |= BIT(25); /* always select PLLU_60M */
- writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC);
- clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0,
- 1, 1);
- clks[TEGRA124_CLK_XUSB_HS_SRC] = clk;
+ /* xusb_ss_div2 */
+ clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0,
+ 1, 2);
+ clks[TEGRA124_CLK_XUSB_SS_DIV2] = clk;
/* dsia mux */
clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0,
@@ -1368,6 +1363,12 @@ static struct tegra_clk_init_table init_table[] __initdata = {
{TEGRA124_CLK_SBC4, TEGRA124_CLK_PLL_P, 12000000, 1},
{TEGRA124_CLK_TSEC, TEGRA124_CLK_PLL_C3, 0, 0},
{TEGRA124_CLK_MSENC, TEGRA124_CLK_PLL_C3, 0, 0},
+ {TEGRA124_CLK_PLL_RE_VCO, TEGRA124_CLK_CLK_MAX, 672000000, 0},
+ {TEGRA124_CLK_XUSB_SS_SRC, TEGRA124_CLK_PLL_U_480M, 120000000, 0},
+ {TEGRA124_CLK_XUSB_FS_SRC, TEGRA124_CLK_PLL_U_48M, 48000000, 0},
+ {TEGRA124_CLK_XUSB_HS_SRC, TEGRA124_CLK_PLL_U_60M, 60000000, 0},
+ {TEGRA124_CLK_XUSB_FALCON_SRC, TEGRA124_CLK_PLL_RE_OUT, 224000000, 0},
+ {TEGRA124_CLK_XUSB_HOST_SRC, TEGRA124_CLK_PLL_RE_OUT, 112000000, 0},
/* This MUST be the last entry. */
{TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
};