Commit fcd5ac1a authored by Michael Turquette's avatar Michael Turquette

Merge tag 'imx-clk-v4.5' of...

Merge tag 'imx-clk-v4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into clk-next

The i.MX clock updates for 4.5:
- Add is_prepared function callback for pllv3 clock driver
- Use imx_check_clocks() on imx6ul and imx7d clock drivers to save
  some code
- Add a core clock for imx7d to support generic cpufreq driver
- Support imx6q clock routing with OSC to anaclk2/2b
- To support more precise pixel clocks on imx5, allow ipu_di_sel clock
  selectors to influence the PLLs that they are derived from
- A cleanup on imx25 OSC clock
parents eaaa6fb5 c20737a2
...@@ -96,13 +96,11 @@ static struct clk ** const uart_clks[] __initconst = { ...@@ -96,13 +96,11 @@ static struct clk ** const uart_clks[] __initconst = {
NULL NULL
}; };
static int __init __mx25_clocks_init(unsigned long osc_rate, static int __init __mx25_clocks_init(void __iomem *ccm_base)
void __iomem *ccm_base)
{ {
BUG_ON(!ccm_base); BUG_ON(!ccm_base);
clk[dummy] = imx_clk_fixed("dummy", 0); clk[dummy] = imx_clk_fixed("dummy", 0);
clk[osc] = imx_clk_fixed("osc", osc_rate);
clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "mpll", "osc", ccm(CCM_MPCTL)); clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "mpll", "osc", ccm(CCM_MPCTL));
clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "upll", "osc", ccm(CCM_UPCTL)); clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "upll", "osc", ccm(CCM_UPCTL));
clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4); clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
...@@ -250,22 +248,10 @@ static int __init __mx25_clocks_init(unsigned long osc_rate, ...@@ -250,22 +248,10 @@ static int __init __mx25_clocks_init(unsigned long osc_rate,
static void __init mx25_clocks_init_dt(struct device_node *np) static void __init mx25_clocks_init_dt(struct device_node *np)
{ {
struct device_node *refnp;
unsigned long osc_rate = 24000000;
void __iomem *ccm; void __iomem *ccm;
/* retrieve the freqency of fixed clocks from device tree */
for_each_compatible_node(refnp, NULL, "fixed-clock") {
u32 rate;
if (of_property_read_u32(refnp, "clock-frequency", &rate))
continue;
if (of_device_is_compatible(refnp, "fsl,imx-osc"))
osc_rate = rate;
}
ccm = of_iomap(np, 0); ccm = of_iomap(np, 0);
__mx25_clocks_init(osc_rate, ccm); __mx25_clocks_init(ccm);
clk_data.clks = clk; clk_data.clks = clk;
clk_data.clk_num = ARRAY_SIZE(clk); clk_data.clk_num = ARRAY_SIZE(clk);
......
...@@ -519,10 +519,10 @@ static void __init mx53_clocks_init(struct device_node *np) ...@@ -519,10 +519,10 @@ static void __init mx53_clocks_init(struct device_node *np)
mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT); mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT);
clk[IMX5_CLK_LDB_DI0_GATE] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28); clk[IMX5_CLK_LDB_DI0_GATE] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
clk[IMX5_CLK_LDB_DI1_GATE] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30); clk[IMX5_CLK_LDB_DI1_GATE] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_flags("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel)); mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel), CLK_SET_RATE_PARENT);
clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux_flags("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel)); mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel), CLK_SET_RATE_PARENT);
clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT); mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT);
clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30); clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
......
...@@ -70,7 +70,8 @@ static const char *cko_sels[] = { "cko1", "cko2", }; ...@@ -70,7 +70,8 @@ static const char *cko_sels[] = { "cko1", "cko2", };
static const char *lvds_sels[] = { static const char *lvds_sels[] = {
"dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
"pll4_audio", "pll5_video", "pll8_mlb", "enet_ref", "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
"pcie_ref_125m", "sata_ref_100m", "pcie_ref_125m", "sata_ref_100m", "usbphy1", "usbphy2",
"dummy", "dummy", "dummy", "dummy", "osc",
}; };
static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", }; static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
......
...@@ -399,9 +399,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) ...@@ -399,9 +399,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
/* mask handshake of mmdc */ /* mask handshake of mmdc */
writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR); writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
for (i = 0; i < ARRAY_SIZE(clks); i++) imx_check_clocks(clks, ARRAY_SIZE(clks));
if (IS_ERR(clks[i]))
pr_err("i.MX6UL clk %d: register failed with %ld\n", i, PTR_ERR(clks[i]));
clk_data.clks = clks; clk_data.clks = clks;
clk_data.clk_num = ARRAY_SIZE(clks); clk_data.clk_num = ARRAY_SIZE(clks);
......
...@@ -833,10 +833,13 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) ...@@ -833,10 +833,13 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
for (i = 0; i < ARRAY_SIZE(clks); i++) clks[IMX7D_CLK_ARM] = imx_clk_cpu("arm", "arm_a7_root_clk",
if (IS_ERR(clks[i])) clks[IMX7D_ARM_A7_ROOT_CLK],
pr_err("i.MX7D clk %d: register failed with %ld\n", clks[IMX7D_ARM_A7_ROOT_SRC],
i, PTR_ERR(clks[i])); clks[IMX7D_PLL_ARM_MAIN_CLK],
clks[IMX7D_PLL_SYS_MAIN_CLK]);
imx_check_clocks(clks, ARRAY_SIZE(clks));
clk_data.clks = clks; clk_data.clks = clks;
clk_data.clk_num = ARRAY_SIZE(clks); clk_data.clk_num = ARRAY_SIZE(clks);
......
...@@ -97,6 +97,16 @@ static void clk_pllv3_unprepare(struct clk_hw *hw) ...@@ -97,6 +97,16 @@ static void clk_pllv3_unprepare(struct clk_hw *hw)
writel_relaxed(val, pll->base); writel_relaxed(val, pll->base);
} }
static int clk_pllv3_is_prepared(struct clk_hw *hw)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
if (readl_relaxed(pll->base) & BM_PLL_LOCK)
return 1;
return 0;
}
static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw, static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate) unsigned long parent_rate)
{ {
...@@ -139,6 +149,7 @@ static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate, ...@@ -139,6 +149,7 @@ static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
static const struct clk_ops clk_pllv3_ops = { static const struct clk_ops clk_pllv3_ops = {
.prepare = clk_pllv3_prepare, .prepare = clk_pllv3_prepare,
.unprepare = clk_pllv3_unprepare, .unprepare = clk_pllv3_unprepare,
.is_prepared = clk_pllv3_is_prepared,
.recalc_rate = clk_pllv3_recalc_rate, .recalc_rate = clk_pllv3_recalc_rate,
.round_rate = clk_pllv3_round_rate, .round_rate = clk_pllv3_round_rate,
.set_rate = clk_pllv3_set_rate, .set_rate = clk_pllv3_set_rate,
...@@ -193,6 +204,7 @@ static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate, ...@@ -193,6 +204,7 @@ static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
static const struct clk_ops clk_pllv3_sys_ops = { static const struct clk_ops clk_pllv3_sys_ops = {
.prepare = clk_pllv3_prepare, .prepare = clk_pllv3_prepare,
.unprepare = clk_pllv3_unprepare, .unprepare = clk_pllv3_unprepare,
.is_prepared = clk_pllv3_is_prepared,
.recalc_rate = clk_pllv3_sys_recalc_rate, .recalc_rate = clk_pllv3_sys_recalc_rate,
.round_rate = clk_pllv3_sys_round_rate, .round_rate = clk_pllv3_sys_round_rate,
.set_rate = clk_pllv3_sys_set_rate, .set_rate = clk_pllv3_sys_set_rate,
...@@ -265,6 +277,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, ...@@ -265,6 +277,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
static const struct clk_ops clk_pllv3_av_ops = { static const struct clk_ops clk_pllv3_av_ops = {
.prepare = clk_pllv3_prepare, .prepare = clk_pllv3_prepare,
.unprepare = clk_pllv3_unprepare, .unprepare = clk_pllv3_unprepare,
.is_prepared = clk_pllv3_is_prepared,
.recalc_rate = clk_pllv3_av_recalc_rate, .recalc_rate = clk_pllv3_av_recalc_rate,
.round_rate = clk_pllv3_av_round_rate, .round_rate = clk_pllv3_av_round_rate,
.set_rate = clk_pllv3_av_set_rate, .set_rate = clk_pllv3_av_set_rate,
...@@ -279,6 +292,7 @@ static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw, ...@@ -279,6 +292,7 @@ static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
static const struct clk_ops clk_pllv3_enet_ops = { static const struct clk_ops clk_pllv3_enet_ops = {
.prepare = clk_pllv3_prepare, .prepare = clk_pllv3_prepare,
.unprepare = clk_pllv3_unprepare, .unprepare = clk_pllv3_unprepare,
.is_prepared = clk_pllv3_is_prepared,
.recalc_rate = clk_pllv3_enet_recalc_rate, .recalc_rate = clk_pllv3_enet_recalc_rate,
}; };
......
...@@ -447,5 +447,6 @@ ...@@ -447,5 +447,6 @@
#define IMX7D_SEMA4_HS_ROOT_CLK 434 #define IMX7D_SEMA4_HS_ROOT_CLK 434
#define IMX7D_PLL_DRAM_TEST_DIV 435 #define IMX7D_PLL_DRAM_TEST_DIV 435
#define IMX7D_ADC_ROOT_CLK 436 #define IMX7D_ADC_ROOT_CLK 436
#define IMX7D_CLK_END 437 #define IMX7D_CLK_ARM 437
#define IMX7D_CLK_END 438
#endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment