Merge branch 'for-4.1-clk-ti' of github.com:t-kristo/linux-pm into clk-next
This commit is contained in:
commit
c77662a4df
14 changed files with 318 additions and 72 deletions
|
@ -203,7 +203,7 @@ static void __init of_dra7_apll_setup(struct device_node *node)
|
|||
ad->control_reg = ti_clk_get_reg_addr(node, 0);
|
||||
ad->idlest_reg = ti_clk_get_reg_addr(node, 1);
|
||||
|
||||
if (!ad->control_reg || !ad->idlest_reg)
|
||||
if (IS_ERR(ad->control_reg) || IS_ERR(ad->idlest_reg))
|
||||
goto cleanup;
|
||||
|
||||
ad->idlest_mask = 0x1;
|
||||
|
@ -384,7 +384,8 @@ static void __init of_omap2_apll_setup(struct device_node *node)
|
|||
ad->autoidle_reg = ti_clk_get_reg_addr(node, 1);
|
||||
ad->idlest_reg = ti_clk_get_reg_addr(node, 2);
|
||||
|
||||
if (!ad->control_reg || !ad->autoidle_reg || !ad->idlest_reg)
|
||||
if (IS_ERR(ad->control_reg) || IS_ERR(ad->autoidle_reg) ||
|
||||
IS_ERR(ad->idlest_reg))
|
||||
goto cleanup;
|
||||
|
||||
clk = clk_register(NULL, &clk_hw->hw);
|
||||
|
|
|
@ -119,7 +119,7 @@ int __init of_ti_clk_autoidle_setup(struct device_node *node)
|
|||
clk->name = node->name;
|
||||
clk->reg = ti_clk_get_reg_addr(node, 0);
|
||||
|
||||
if (!clk->reg) {
|
||||
if (IS_ERR(clk->reg)) {
|
||||
kfree(clk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -4320,7 +4320,6 @@ static struct ti_clk_alias omap3xxx_clks[] = {
|
|||
CLK(NULL, "dpll3_m3x2_ck", &dpll3_m3x2_ck),
|
||||
CLK("etb", "emu_core_alwon_ck", &emu_core_alwon_ck),
|
||||
CLK(NULL, "sys_altclk", &sys_altclk),
|
||||
CLK(NULL, "mcbsp_clks", &mcbsp_clks),
|
||||
CLK(NULL, "sys_clkout1", &sys_clkout1),
|
||||
CLK(NULL, "dpll3_m2_ck", &dpll3_m2_ck),
|
||||
CLK(NULL, "core_ck", &core_ck),
|
||||
|
@ -4369,8 +4368,6 @@ static struct ti_clk_alias omap3xxx_clks[] = {
|
|||
CLK(NULL, "i2c3_fck", &i2c3_fck),
|
||||
CLK(NULL, "i2c2_fck", &i2c2_fck),
|
||||
CLK(NULL, "i2c1_fck", &i2c1_fck),
|
||||
CLK(NULL, "mcbsp5_fck", &mcbsp5_fck),
|
||||
CLK(NULL, "mcbsp1_fck", &mcbsp1_fck),
|
||||
CLK(NULL, "core_48m_fck", &core_48m_fck),
|
||||
CLK(NULL, "mcspi4_fck", &mcspi4_fck),
|
||||
CLK(NULL, "mcspi3_fck", &mcspi3_fck),
|
||||
|
@ -4409,8 +4406,6 @@ static struct ti_clk_alias omap3xxx_clks[] = {
|
|||
CLK(NULL, "uart1_ick", &uart1_ick),
|
||||
CLK(NULL, "gpt11_ick", &gpt11_ick),
|
||||
CLK(NULL, "gpt10_ick", &gpt10_ick),
|
||||
CLK("omap-mcbsp.5", "ick", &mcbsp5_ick),
|
||||
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick),
|
||||
CLK(NULL, "mcbsp5_ick", &mcbsp5_ick),
|
||||
CLK(NULL, "mcbsp1_ick", &mcbsp1_ick),
|
||||
CLK(NULL, "omapctrl_ick", &omapctrl_ick),
|
||||
|
@ -4467,15 +4462,22 @@ static struct ti_clk_alias omap3xxx_clks[] = {
|
|||
CLK(NULL, "gpt4_ick", &gpt4_ick),
|
||||
CLK(NULL, "gpt3_ick", &gpt3_ick),
|
||||
CLK(NULL, "gpt2_ick", &gpt2_ick),
|
||||
CLK(NULL, "mcbsp_clks", &mcbsp_clks),
|
||||
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick),
|
||||
CLK("omap-mcbsp.2", "ick", &mcbsp2_ick),
|
||||
CLK("omap-mcbsp.3", "ick", &mcbsp3_ick),
|
||||
CLK("omap-mcbsp.4", "ick", &mcbsp4_ick),
|
||||
CLK(NULL, "mcbsp4_ick", &mcbsp2_ick),
|
||||
CLK("omap-mcbsp.5", "ick", &mcbsp5_ick),
|
||||
CLK(NULL, "mcbsp1_ick", &mcbsp1_ick),
|
||||
CLK(NULL, "mcbsp2_ick", &mcbsp2_ick),
|
||||
CLK(NULL, "mcbsp3_ick", &mcbsp3_ick),
|
||||
CLK(NULL, "mcbsp2_ick", &mcbsp4_ick),
|
||||
CLK(NULL, "mcbsp4_ick", &mcbsp4_ick),
|
||||
CLK(NULL, "mcbsp5_ick", &mcbsp5_ick),
|
||||
CLK(NULL, "mcbsp1_fck", &mcbsp1_fck),
|
||||
CLK(NULL, "mcbsp2_fck", &mcbsp2_fck),
|
||||
CLK(NULL, "mcbsp3_fck", &mcbsp3_fck),
|
||||
CLK(NULL, "mcbsp4_fck", &mcbsp4_fck),
|
||||
CLK(NULL, "mcbsp5_fck", &mcbsp5_fck),
|
||||
CLK(NULL, "emu_src_mux_ck", &emu_src_mux_ck),
|
||||
CLK("etb", "emu_src_ck", &emu_src_ck),
|
||||
CLK(NULL, "emu_src_mux_ck", &emu_src_mux_ck),
|
||||
|
|
|
@ -34,7 +34,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
|
|||
DT_CLK(NULL, "omap_96m_alwon_fck", "omap_96m_alwon_fck"),
|
||||
DT_CLK("etb", "emu_core_alwon_ck", "emu_core_alwon_ck"),
|
||||
DT_CLK(NULL, "sys_altclk", "sys_altclk"),
|
||||
DT_CLK(NULL, "mcbsp_clks", "mcbsp_clks"),
|
||||
DT_CLK(NULL, "sys_clkout1", "sys_clkout1"),
|
||||
DT_CLK(NULL, "dpll1_ck", "dpll1_ck"),
|
||||
DT_CLK(NULL, "dpll1_x2_ck", "dpll1_x2_ck"),
|
||||
|
@ -82,8 +81,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
|
|||
DT_CLK(NULL, "i2c3_fck", "i2c3_fck"),
|
||||
DT_CLK(NULL, "i2c2_fck", "i2c2_fck"),
|
||||
DT_CLK(NULL, "i2c1_fck", "i2c1_fck"),
|
||||
DT_CLK(NULL, "mcbsp5_fck", "mcbsp5_fck"),
|
||||
DT_CLK(NULL, "mcbsp1_fck", "mcbsp1_fck"),
|
||||
DT_CLK(NULL, "core_48m_fck", "core_48m_fck"),
|
||||
DT_CLK(NULL, "mcspi4_fck", "mcspi4_fck"),
|
||||
DT_CLK(NULL, "mcspi3_fck", "mcspi3_fck"),
|
||||
|
@ -122,10 +119,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
|
|||
DT_CLK(NULL, "uart1_ick", "uart1_ick"),
|
||||
DT_CLK(NULL, "gpt11_ick", "gpt11_ick"),
|
||||
DT_CLK(NULL, "gpt10_ick", "gpt10_ick"),
|
||||
DT_CLK("omap-mcbsp.5", "ick", "mcbsp5_ick"),
|
||||
DT_CLK("omap-mcbsp.1", "ick", "mcbsp1_ick"),
|
||||
DT_CLK(NULL, "mcbsp5_ick", "mcbsp5_ick"),
|
||||
DT_CLK(NULL, "mcbsp1_ick", "mcbsp1_ick"),
|
||||
DT_CLK(NULL, "omapctrl_ick", "omapctrl_ick"),
|
||||
DT_CLK(NULL, "dss_tv_fck", "dss_tv_fck"),
|
||||
DT_CLK(NULL, "dss_96m_fck", "dss_96m_fck"),
|
||||
|
@ -179,15 +172,17 @@ static struct ti_dt_clk omap3xxx_clks[] = {
|
|||
DT_CLK(NULL, "gpt4_ick", "gpt4_ick"),
|
||||
DT_CLK(NULL, "gpt3_ick", "gpt3_ick"),
|
||||
DT_CLK(NULL, "gpt2_ick", "gpt2_ick"),
|
||||
DT_CLK("omap-mcbsp.2", "ick", "mcbsp2_ick"),
|
||||
DT_CLK("omap-mcbsp.3", "ick", "mcbsp3_ick"),
|
||||
DT_CLK("omap-mcbsp.4", "ick", "mcbsp4_ick"),
|
||||
DT_CLK(NULL, "mcbsp4_ick", "mcbsp2_ick"),
|
||||
DT_CLK(NULL, "mcbsp_clks", "mcbsp_clks"),
|
||||
DT_CLK(NULL, "mcbsp1_ick", "mcbsp1_ick"),
|
||||
DT_CLK(NULL, "mcbsp2_ick", "mcbsp2_ick"),
|
||||
DT_CLK(NULL, "mcbsp3_ick", "mcbsp3_ick"),
|
||||
DT_CLK(NULL, "mcbsp2_ick", "mcbsp4_ick"),
|
||||
DT_CLK(NULL, "mcbsp4_ick", "mcbsp4_ick"),
|
||||
DT_CLK(NULL, "mcbsp5_ick", "mcbsp5_ick"),
|
||||
DT_CLK(NULL, "mcbsp1_fck", "mcbsp1_fck"),
|
||||
DT_CLK(NULL, "mcbsp2_fck", "mcbsp2_fck"),
|
||||
DT_CLK(NULL, "mcbsp3_fck", "mcbsp3_fck"),
|
||||
DT_CLK(NULL, "mcbsp4_fck", "mcbsp4_fck"),
|
||||
DT_CLK(NULL, "mcbsp5_fck", "mcbsp5_fck"),
|
||||
DT_CLK("etb", "emu_src_ck", "emu_src_ck"),
|
||||
DT_CLK(NULL, "emu_src_ck", "emu_src_ck"),
|
||||
DT_CLK(NULL, "pclk_fck", "pclk_fck"),
|
||||
|
|
|
@ -249,17 +249,6 @@ static struct ti_dt_clk omap44xx_clks[] = {
|
|||
DT_CLK("usbhs_tll", "usbtll_fck", "dummy_ck"),
|
||||
DT_CLK("omap_wdt", "ick", "dummy_ck"),
|
||||
DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
|
||||
DT_CLK("omap_timer.1", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.2", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.3", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.4", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.9", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.10", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.11", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.5", "timer_sys_ck", "syc_clk_div_ck"),
|
||||
DT_CLK("omap_timer.6", "timer_sys_ck", "syc_clk_div_ck"),
|
||||
DT_CLK("omap_timer.7", "timer_sys_ck", "syc_clk_div_ck"),
|
||||
DT_CLK("omap_timer.8", "timer_sys_ck", "syc_clk_div_ck"),
|
||||
DT_CLK("4a318000.timer", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin_ck"),
|
||||
|
|
|
@ -208,17 +208,17 @@ static struct ti_dt_clk omap54xx_clks[] = {
|
|||
DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"),
|
||||
DT_CLK("omap_wdt", "ick", "dummy_ck"),
|
||||
DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
|
||||
DT_CLK("omap_timer.1", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.2", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.3", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.4", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.9", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.10", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.11", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.5", "sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("omap_timer.6", "sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("omap_timer.7", "sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("omap_timer.8", "sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("4ae18000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("48036000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("4803e000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("48086000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("48088000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("40138000.timer", "timer_sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("4013a000.timer", "timer_sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("4013c000.timer", "timer_sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("4013e000.timer", "timer_sys_ck", "dss_syc_gfclk_div"),
|
||||
{ .node_name = NULL },
|
||||
};
|
||||
|
||||
|
|
|
@ -289,17 +289,21 @@ static struct ti_dt_clk dra7xx_clks[] = {
|
|||
DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"),
|
||||
DT_CLK("omap_wdt", "ick", "dummy_ck"),
|
||||
DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
|
||||
DT_CLK("4ae18000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("48036000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("4803e000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("48086000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("48088000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("4ae18000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48032000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48034000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48036000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("4803e000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48086000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48088000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48820000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48822000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48824000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48826000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48828000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("4882a000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("4882c000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("4882e000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK(NULL, "sys_clkin", "sys_clkin1"),
|
||||
{ .node_name = NULL },
|
||||
};
|
||||
|
|
|
@ -103,7 +103,8 @@ int __init ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
|
|||
* @index: register index from the clock node
|
||||
*
|
||||
* Builds clock register address from device tree information. This
|
||||
* is a struct of type clk_omap_reg.
|
||||
* is a struct of type clk_omap_reg. Returns a pointer to the register
|
||||
* address, or a pointer error value in failure.
|
||||
*/
|
||||
void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
|
||||
{
|
||||
|
@ -121,14 +122,14 @@ void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
|
|||
|
||||
if (i == CLK_MAX_MEMMAPS) {
|
||||
pr_err("clk-provider not found for %s!\n", node->name);
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
reg->index = i;
|
||||
|
||||
if (of_property_read_u32_index(node, "reg", index, &val)) {
|
||||
pr_err("%s must have reg[%d]!\n", node->name, index);
|
||||
return NULL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
reg->offset = val;
|
||||
|
|
|
@ -530,8 +530,8 @@ static int __init ti_clk_divider_populate(struct device_node *node,
|
|||
u32 val;
|
||||
|
||||
*reg = ti_clk_get_reg_addr(node, 0);
|
||||
if (!*reg)
|
||||
return -EINVAL;
|
||||
if (IS_ERR(*reg))
|
||||
return PTR_ERR(*reg);
|
||||
|
||||
if (!of_property_read_u32(node, "ti,bit-shift", &val))
|
||||
*shift = val;
|
||||
|
|
|
@ -390,18 +390,18 @@ static void __init of_ti_dpll_setup(struct device_node *node,
|
|||
#endif
|
||||
} else {
|
||||
dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
|
||||
if (!dd->idlest_reg)
|
||||
if (IS_ERR(dd->idlest_reg))
|
||||
goto cleanup;
|
||||
|
||||
dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
|
||||
}
|
||||
|
||||
if (!dd->control_reg || !dd->mult_div1_reg)
|
||||
if (IS_ERR(dd->control_reg) || IS_ERR(dd->mult_div1_reg))
|
||||
goto cleanup;
|
||||
|
||||
if (dd->autoidle_mask) {
|
||||
dd->autoidle_reg = ti_clk_get_reg_addr(node, 3);
|
||||
if (!dd->autoidle_reg)
|
||||
if (IS_ERR(dd->autoidle_reg))
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,19 +11,27 @@
|
|||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/clk/ti.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
/* FAPLL Control Register PLL_CTRL */
|
||||
#define FAPLL_MAIN_MULT_N_SHIFT 16
|
||||
#define FAPLL_MAIN_DIV_P_SHIFT 8
|
||||
#define FAPLL_MAIN_LOCK BIT(7)
|
||||
#define FAPLL_MAIN_PLLEN BIT(3)
|
||||
#define FAPLL_MAIN_BP BIT(2)
|
||||
#define FAPLL_MAIN_LOC_CTL BIT(0)
|
||||
|
||||
#define FAPLL_MAIN_MAX_MULT_N 0xffff
|
||||
#define FAPLL_MAIN_MAX_DIV_P 0xff
|
||||
#define FAPLL_MAIN_CLEAR_MASK \
|
||||
((FAPLL_MAIN_MAX_MULT_N << FAPLL_MAIN_MULT_N_SHIFT) | \
|
||||
(FAPLL_MAIN_DIV_P_SHIFT << FAPLL_MAIN_DIV_P_SHIFT) | \
|
||||
FAPLL_MAIN_LOC_CTL)
|
||||
|
||||
/* FAPLL powerdown register PWD */
|
||||
#define FAPLL_PWD_OFFSET 4
|
||||
|
||||
|
@ -49,6 +57,10 @@
|
|||
/* Synthesizer frequency register */
|
||||
#define SYNTH_LDFREQ BIT(31)
|
||||
|
||||
#define SYNTH_PHASE_K 8
|
||||
#define SYNTH_MAX_INT_DIV 0xf
|
||||
#define SYNTH_MAX_DIV_M 0xff
|
||||
|
||||
struct fapll_data {
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
|
@ -79,6 +91,48 @@ static bool ti_fapll_clock_is_bypass(struct fapll_data *fd)
|
|||
return !!(v & FAPLL_MAIN_BP);
|
||||
}
|
||||
|
||||
static void ti_fapll_set_bypass(struct fapll_data *fd)
|
||||
{
|
||||
u32 v = readl_relaxed(fd->base);
|
||||
|
||||
if (fd->bypass_bit_inverted)
|
||||
v &= ~FAPLL_MAIN_BP;
|
||||
else
|
||||
v |= FAPLL_MAIN_BP;
|
||||
writel_relaxed(v, fd->base);
|
||||
}
|
||||
|
||||
static void ti_fapll_clear_bypass(struct fapll_data *fd)
|
||||
{
|
||||
u32 v = readl_relaxed(fd->base);
|
||||
|
||||
if (fd->bypass_bit_inverted)
|
||||
v |= FAPLL_MAIN_BP;
|
||||
else
|
||||
v &= ~FAPLL_MAIN_BP;
|
||||
writel_relaxed(v, fd->base);
|
||||
}
|
||||
|
||||
static int ti_fapll_wait_lock(struct fapll_data *fd)
|
||||
{
|
||||
int retries = FAPLL_MAX_RETRIES;
|
||||
u32 v;
|
||||
|
||||
while ((v = readl_relaxed(fd->base))) {
|
||||
if (v & FAPLL_MAIN_LOCK)
|
||||
return 0;
|
||||
|
||||
if (retries-- <= 0)
|
||||
break;
|
||||
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
pr_err("%s failed to lock\n", fd->name);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int ti_fapll_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct fapll_data *fd = to_fapll(hw);
|
||||
|
@ -86,6 +140,7 @@ static int ti_fapll_enable(struct clk_hw *hw)
|
|||
|
||||
v |= FAPLL_MAIN_PLLEN;
|
||||
writel_relaxed(v, fd->base);
|
||||
ti_fapll_wait_lock(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -141,12 +196,85 @@ static u8 ti_fapll_get_parent(struct clk_hw *hw)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ti_fapll_set_div_mult(unsigned long rate,
|
||||
unsigned long parent_rate,
|
||||
u32 *pre_div_p, u32 *mult_n)
|
||||
{
|
||||
/*
|
||||
* So far no luck getting decent clock with PLL divider,
|
||||
* PLL does not seem to lock and the signal does not look
|
||||
* right. It seems the divider can only be used together
|
||||
* with the multiplier?
|
||||
*/
|
||||
if (rate < parent_rate) {
|
||||
pr_warn("FAPLL main divider rates unsupported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*mult_n = rate / parent_rate;
|
||||
if (*mult_n > FAPLL_MAIN_MAX_MULT_N)
|
||||
return -EINVAL;
|
||||
*pre_div_p = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long ti_fapll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
u32 pre_div_p, mult_n;
|
||||
int error;
|
||||
|
||||
if (!rate)
|
||||
return -EINVAL;
|
||||
|
||||
error = ti_fapll_set_div_mult(rate, *parent_rate,
|
||||
&pre_div_p, &mult_n);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
rate = *parent_rate / pre_div_p;
|
||||
rate *= mult_n;
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
static int ti_fapll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct fapll_data *fd = to_fapll(hw);
|
||||
u32 pre_div_p, mult_n, v;
|
||||
int error;
|
||||
|
||||
if (!rate)
|
||||
return -EINVAL;
|
||||
|
||||
error = ti_fapll_set_div_mult(rate, parent_rate,
|
||||
&pre_div_p, &mult_n);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
ti_fapll_set_bypass(fd);
|
||||
v = readl_relaxed(fd->base);
|
||||
v &= ~FAPLL_MAIN_CLEAR_MASK;
|
||||
v |= pre_div_p << FAPLL_MAIN_DIV_P_SHIFT;
|
||||
v |= mult_n << FAPLL_MAIN_MULT_N_SHIFT;
|
||||
writel_relaxed(v, fd->base);
|
||||
if (ti_fapll_is_enabled(hw))
|
||||
ti_fapll_wait_lock(fd);
|
||||
ti_fapll_clear_bypass(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk_ops ti_fapll_ops = {
|
||||
.enable = ti_fapll_enable,
|
||||
.disable = ti_fapll_disable,
|
||||
.is_enabled = ti_fapll_is_enabled,
|
||||
.recalc_rate = ti_fapll_recalc_rate,
|
||||
.get_parent = ti_fapll_get_parent,
|
||||
.round_rate = ti_fapll_round_rate,
|
||||
.set_rate = ti_fapll_set_rate,
|
||||
};
|
||||
|
||||
static int ti_fapll_synth_enable(struct clk_hw *hw)
|
||||
|
@ -204,7 +332,7 @@ static unsigned long ti_fapll_synth_recalc_rate(struct clk_hw *hw,
|
|||
/*
|
||||
* Synth frequency integer and fractional divider.
|
||||
* Note that the phase output K is 8, so the result needs
|
||||
* to be multiplied by 8.
|
||||
* to be multiplied by SYNTH_PHASE_K.
|
||||
*/
|
||||
if (synth->freq) {
|
||||
u32 v, synth_int_div, synth_frac_div, synth_div_freq;
|
||||
|
@ -215,14 +343,138 @@ static unsigned long ti_fapll_synth_recalc_rate(struct clk_hw *hw,
|
|||
synth_div_freq = (synth_int_div * 10000000) + synth_frac_div;
|
||||
rate *= 10000000;
|
||||
do_div(rate, synth_div_freq);
|
||||
rate *= 8;
|
||||
rate *= SYNTH_PHASE_K;
|
||||
}
|
||||
|
||||
/* Synth ost-divider M */
|
||||
synth_div_m = readl_relaxed(synth->div) & 0xff;
|
||||
do_div(rate, synth_div_m);
|
||||
/* Synth post-divider M */
|
||||
synth_div_m = readl_relaxed(synth->div) & SYNTH_MAX_DIV_M;
|
||||
|
||||
return rate;
|
||||
return DIV_ROUND_UP_ULL(rate, synth_div_m);
|
||||
}
|
||||
|
||||
static unsigned long ti_fapll_synth_get_frac_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct fapll_synth *synth = to_synth(hw);
|
||||
unsigned long current_rate, frac_rate;
|
||||
u32 post_div_m;
|
||||
|
||||
current_rate = ti_fapll_synth_recalc_rate(hw, parent_rate);
|
||||
post_div_m = readl_relaxed(synth->div) & SYNTH_MAX_DIV_M;
|
||||
frac_rate = current_rate * post_div_m;
|
||||
|
||||
return frac_rate;
|
||||
}
|
||||
|
||||
static u32 ti_fapll_synth_set_frac_rate(struct fapll_synth *synth,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
u32 post_div_m, synth_int_div = 0, synth_frac_div = 0, v;
|
||||
|
||||
post_div_m = DIV_ROUND_UP_ULL((u64)parent_rate * SYNTH_PHASE_K, rate);
|
||||
post_div_m = post_div_m / SYNTH_MAX_INT_DIV;
|
||||
if (post_div_m > SYNTH_MAX_DIV_M)
|
||||
return -EINVAL;
|
||||
if (!post_div_m)
|
||||
post_div_m = 1;
|
||||
|
||||
for (; post_div_m < SYNTH_MAX_DIV_M; post_div_m++) {
|
||||
synth_int_div = DIV_ROUND_UP_ULL((u64)parent_rate *
|
||||
SYNTH_PHASE_K *
|
||||
10000000,
|
||||
rate * post_div_m);
|
||||
synth_frac_div = synth_int_div % 10000000;
|
||||
synth_int_div /= 10000000;
|
||||
|
||||
if (synth_int_div <= SYNTH_MAX_INT_DIV)
|
||||
break;
|
||||
}
|
||||
|
||||
if (synth_int_div > SYNTH_MAX_INT_DIV)
|
||||
return -EINVAL;
|
||||
|
||||
v = readl_relaxed(synth->freq);
|
||||
v &= ~0x1fffffff;
|
||||
v |= (synth_int_div & SYNTH_MAX_INT_DIV) << 24;
|
||||
v |= (synth_frac_div & 0xffffff);
|
||||
v |= SYNTH_LDFREQ;
|
||||
writel_relaxed(v, synth->freq);
|
||||
|
||||
return post_div_m;
|
||||
}
|
||||
|
||||
static long ti_fapll_synth_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct fapll_synth *synth = to_synth(hw);
|
||||
struct fapll_data *fd = synth->fd;
|
||||
unsigned long r;
|
||||
|
||||
if (ti_fapll_clock_is_bypass(fd) || !synth->div || !rate)
|
||||
return -EINVAL;
|
||||
|
||||
/* Only post divider m available with no fractional divider? */
|
||||
if (!synth->freq) {
|
||||
unsigned long frac_rate;
|
||||
u32 synth_post_div_m;
|
||||
|
||||
frac_rate = ti_fapll_synth_get_frac_rate(hw, *parent_rate);
|
||||
synth_post_div_m = DIV_ROUND_UP(frac_rate, rate);
|
||||
r = DIV_ROUND_UP(frac_rate, synth_post_div_m);
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = *parent_rate * SYNTH_PHASE_K;
|
||||
if (rate > r)
|
||||
goto out;
|
||||
|
||||
r = DIV_ROUND_UP_ULL(r, SYNTH_MAX_INT_DIV * SYNTH_MAX_DIV_M);
|
||||
if (rate < r)
|
||||
goto out;
|
||||
|
||||
r = rate;
|
||||
out:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int ti_fapll_synth_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct fapll_synth *synth = to_synth(hw);
|
||||
struct fapll_data *fd = synth->fd;
|
||||
unsigned long frac_rate, post_rate = 0;
|
||||
u32 post_div_m = 0, v;
|
||||
|
||||
if (ti_fapll_clock_is_bypass(fd) || !synth->div || !rate)
|
||||
return -EINVAL;
|
||||
|
||||
/* Produce the rate with just post divider M? */
|
||||
frac_rate = ti_fapll_synth_get_frac_rate(hw, parent_rate);
|
||||
if (frac_rate < rate) {
|
||||
if (!synth->freq)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
post_div_m = DIV_ROUND_UP(frac_rate, rate);
|
||||
if (post_div_m && (post_div_m <= SYNTH_MAX_DIV_M))
|
||||
post_rate = DIV_ROUND_UP(frac_rate, post_div_m);
|
||||
if (!synth->freq && !post_rate)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Need to recalculate the fractional divider? */
|
||||
if ((post_rate != rate) && synth->freq)
|
||||
post_div_m = ti_fapll_synth_set_frac_rate(synth,
|
||||
rate,
|
||||
parent_rate);
|
||||
|
||||
v = readl_relaxed(synth->div);
|
||||
v &= ~SYNTH_MAX_DIV_M;
|
||||
v |= post_div_m;
|
||||
v |= SYNTH_LDMDIV1;
|
||||
writel_relaxed(v, synth->div);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk_ops ti_fapll_synt_ops = {
|
||||
|
@ -230,6 +482,8 @@ static struct clk_ops ti_fapll_synt_ops = {
|
|||
.disable = ti_fapll_synth_disable,
|
||||
.is_enabled = ti_fapll_synth_is_enabled,
|
||||
.recalc_rate = ti_fapll_synth_recalc_rate,
|
||||
.round_rate = ti_fapll_synth_round_rate,
|
||||
.set_rate = ti_fapll_synth_set_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init ti_fapll_synth_setup(struct fapll_data *fd,
|
||||
|
|
|
@ -225,7 +225,7 @@ static void __init _of_ti_gate_clk_setup(struct device_node *node,
|
|||
|
||||
if (ops != &omap_gate_clkdm_clk_ops) {
|
||||
reg = ti_clk_get_reg_addr(node, 0);
|
||||
if (!reg)
|
||||
if (IS_ERR(reg))
|
||||
return;
|
||||
|
||||
if (!of_property_read_u32(node, "ti,bit-shift", &val))
|
||||
|
@ -264,7 +264,7 @@ _of_ti_composite_gate_clk_setup(struct device_node *node,
|
|||
return;
|
||||
|
||||
gate->enable_reg = ti_clk_get_reg_addr(node, 0);
|
||||
if (!gate->enable_reg)
|
||||
if (IS_ERR(gate->enable_reg))
|
||||
goto cleanup;
|
||||
|
||||
of_property_read_u32(node, "ti,bit-shift", &val);
|
||||
|
|
|
@ -111,7 +111,7 @@ static void __init _of_ti_interface_clk_setup(struct device_node *node,
|
|||
u32 val;
|
||||
|
||||
reg = ti_clk_get_reg_addr(node, 0);
|
||||
if (!reg)
|
||||
if (IS_ERR(reg))
|
||||
return;
|
||||
|
||||
if (!of_property_read_u32(node, "ti,bit-shift", &val))
|
||||
|
|
|
@ -210,7 +210,7 @@ static void of_mux_clk_setup(struct device_node *node)
|
|||
|
||||
reg = ti_clk_get_reg_addr(node, 0);
|
||||
|
||||
if (!reg)
|
||||
if (IS_ERR(reg))
|
||||
goto cleanup;
|
||||
|
||||
of_property_read_u32(node, "ti,bit-shift", &shift);
|
||||
|
@ -283,7 +283,7 @@ static void __init of_ti_composite_mux_clk_setup(struct device_node *node)
|
|||
|
||||
mux->reg = ti_clk_get_reg_addr(node, 0);
|
||||
|
||||
if (!mux->reg)
|
||||
if (IS_ERR(mux->reg))
|
||||
goto cleanup;
|
||||
|
||||
if (!of_property_read_u32(node, "ti,bit-shift", &val))
|
||||
|
|
Loading…
Reference in a new issue