- Various clock fixes and enhancements
This commit is contained in:
Tom Rini 2020-01-27 07:19:26 -05:00
commit 051e03c0d7
9 changed files with 34 additions and 106 deletions

View file

@ -374,28 +374,6 @@ void init_wdog_clk(void)
clock_enable(CCGR_WDOG3, 1); clock_enable(CCGR_WDOG3, 1);
} }
void init_usb_clk(void)
{
if (!is_usb_boot()) {
clock_enable(CCGR_USB_CTRL1, 0);
clock_enable(CCGR_USB_CTRL2, 0);
clock_enable(CCGR_USB_PHY1, 0);
clock_enable(CCGR_USB_PHY2, 0);
/* 500MHz */
clock_set_target_val(USB_BUS_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(1));
/* 100MHz */
clock_set_target_val(USB_CORE_REF_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(1));
/* 100MHz */
clock_set_target_val(USB_PHY_REF_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(1));
clock_enable(CCGR_USB_CTRL1, 1);
clock_enable(CCGR_USB_CTRL2, 1);
clock_enable(CCGR_USB_PHY1, 1);
clock_enable(CCGR_USB_PHY2, 1);
}
}
void init_nand_clk(void) void init_nand_clk(void)
{ {
@ -658,7 +636,7 @@ void dram_pll_init(ulong pll_val)
; ;
} }
int frac_pll_init(u32 pll, enum frac_pll_out_val val) static int frac_pll_init(u32 pll, enum frac_pll_out_val val)
{ {
void __iomem *pll_cfg0, __iomem *pll_cfg1; void __iomem *pll_cfg0, __iomem *pll_cfg1;
u32 val_cfg0, val_cfg1; u32 val_cfg0, val_cfg1;
@ -699,77 +677,6 @@ int frac_pll_init(u32 pll, enum frac_pll_out_val val)
return 0; return 0;
} }
int sscg_pll_init(u32 pll)
{
void __iomem *pll_cfg0, __iomem *pll_cfg1, __iomem *pll_cfg2;
u32 val_cfg0, val_cfg1, val_cfg2, val;
u32 bypass1_mask = 0x20, bypass2_mask = 0x10;
int ret;
switch (pll) {
case ANATOP_SYSTEM_PLL1:
pll_cfg0 = &ana_pll->sys_pll1_cfg0;
pll_cfg1 = &ana_pll->sys_pll1_cfg1;
pll_cfg2 = &ana_pll->sys_pll1_cfg2;
/* 800MHz */
val_cfg2 = SSCG_PLL_FEEDBACK_DIV_F1_VAL(3) |
SSCG_PLL_FEEDBACK_DIV_F2_VAL(3);
val_cfg1 = 0;
val_cfg0 = SSCG_PLL_CLKE_MASK | SSCG_PLL_DIV2_CLKE_MASK |
SSCG_PLL_DIV3_CLKE_MASK | SSCG_PLL_DIV4_CLKE_MASK |
SSCG_PLL_DIV5_CLKE_MASK | SSCG_PLL_DIV6_CLKE_MASK |
SSCG_PLL_DIV8_CLKE_MASK | SSCG_PLL_DIV10_CLKE_MASK |
SSCG_PLL_DIV20_CLKE_MASK | SSCG_PLL_LOCK_SEL_MASK |
SSCG_PLL_REFCLK_SEL_OSC_25M;
break;
case ANATOP_SYSTEM_PLL2:
pll_cfg0 = &ana_pll->sys_pll2_cfg0;
pll_cfg1 = &ana_pll->sys_pll2_cfg1;
pll_cfg2 = &ana_pll->sys_pll2_cfg2;
/* 1000MHz */
val_cfg2 = SSCG_PLL_FEEDBACK_DIV_F1_VAL(3) |
SSCG_PLL_FEEDBACK_DIV_F2_VAL(4);
val_cfg1 = 0;
val_cfg0 = SSCG_PLL_CLKE_MASK | SSCG_PLL_DIV2_CLKE_MASK |
SSCG_PLL_DIV3_CLKE_MASK | SSCG_PLL_DIV4_CLKE_MASK |
SSCG_PLL_DIV5_CLKE_MASK | SSCG_PLL_DIV6_CLKE_MASK |
SSCG_PLL_DIV8_CLKE_MASK | SSCG_PLL_DIV10_CLKE_MASK |
SSCG_PLL_DIV20_CLKE_MASK | SSCG_PLL_LOCK_SEL_MASK |
SSCG_PLL_REFCLK_SEL_OSC_25M;
break;
case ANATOP_SYSTEM_PLL3:
pll_cfg0 = &ana_pll->sys_pll3_cfg0;
pll_cfg1 = &ana_pll->sys_pll3_cfg1;
pll_cfg2 = &ana_pll->sys_pll3_cfg2;
/* 800MHz */
val_cfg2 = SSCG_PLL_FEEDBACK_DIV_F1_VAL(3) |
SSCG_PLL_FEEDBACK_DIV_F2_VAL(3);
val_cfg1 = 0;
val_cfg0 = SSCG_PLL_PLL3_CLKE_MASK | SSCG_PLL_LOCK_SEL_MASK |
SSCG_PLL_REFCLK_SEL_OSC_25M;
break;
default:
return -EINVAL;
}
/*bypass*/
setbits_le32(pll_cfg0, bypass1_mask | bypass2_mask);
/* set value */
writel(val_cfg2, pll_cfg2);
writel(val_cfg1, pll_cfg1);
/*unbypass1 and wait 70us */
writel(val_cfg0 | bypass2_mask, pll_cfg1);
__udelay(70);
/* unbypass2 and wait lock */
writel(val_cfg0, pll_cfg1);
ret = readl_poll_timeout(pll_cfg0, val, val & SSCG_PLL_LOCK_MASK, 1);
if (ret)
printf("%s timeout\n", __func__);
return ret;
}
int clock_init(void) int clock_init(void)
{ {
@ -833,7 +740,7 @@ int clock_init(void)
* Dump some clockes. * Dump some clockes.
*/ */
#ifndef CONFIG_SPL_BUILD #ifndef CONFIG_SPL_BUILD
int do_imx8m_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, static int do_imx8m_showclocks(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[]) char * const argv[])
{ {
u32 freq; u32 freq;

View file

@ -326,7 +326,6 @@ int clk_set_defaults(struct udevice *dev, int stage)
return 0; return 0;
} }
# endif /* OF_PLATDATA */
int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk) int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
{ {
@ -343,6 +342,7 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
return clk_get_by_index(dev, index, clk); return clk_get_by_index(dev, index, clk);
} }
# endif /* OF_PLATDATA */
int clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk) int clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk)
{ {

View file

@ -20,8 +20,10 @@ int clk_register(struct clk *clk, const char *drv_name,
int ret; int ret;
ret = uclass_get_device_by_name(UCLASS_CLK, parent_name, &parent); ret = uclass_get_device_by_name(UCLASS_CLK, parent_name, &parent);
if (ret) if (ret) {
printf("%s: UCLASS parent: 0x%p\n", __func__, parent); printf("%s: name: %s parent: %s [0x%p]\n",
__func__, name, parent->name, parent);
}
debug("%s: name: %s parent: %s [0x%p]\n", __func__, name, parent->name, debug("%s: name: %s parent: %s [0x%p]\n", __func__, name, parent->name,
parent); parent);

View file

@ -115,7 +115,7 @@ static int imx6q_clk_probe(struct udevice *dev)
/* CCM clocks */ /* CCM clocks */
base = dev_read_addr_ptr(dev); base = dev_read_addr_ptr(dev);
if (base == (void *)FDT_ADDR_T_NONE) if (!base)
return -EINVAL; return -EINVAL;
clk_dm(IMX6QDL_CLK_USDHC1_SEL, clk_dm(IMX6QDL_CLK_USDHC1_SEL,

View file

@ -323,7 +323,7 @@ static int imx8mm_clk_probe(struct udevice *dev)
imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1)); imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1));
base = dev_read_addr_ptr(dev); base = dev_read_addr_ptr(dev);
if (base == (void *)FDT_ADDR_T_NONE) if (!base)
return -EINVAL; return -EINVAL;
clk_dm(IMX8MM_CLK_A53_SRC, clk_dm(IMX8MM_CLK_A53_SRC,

View file

@ -293,7 +293,7 @@ static int imx8mn_clk_probe(struct udevice *dev)
imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1)); imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1));
base = dev_read_addr_ptr(dev); base = dev_read_addr_ptr(dev);
if (base == (void *)FDT_ADDR_T_NONE) if (!base)
return -EINVAL; return -EINVAL;
clk_dm(IMX8MN_CLK_A53_SRC, clk_dm(IMX8MN_CLK_A53_SRC,

View file

@ -121,10 +121,16 @@ static ulong clk_pllv3_sys_set_rate(struct clk *clk, ulong rate)
{ {
struct clk_pllv3 *pll = to_clk_pllv3(clk); struct clk_pllv3 *pll = to_clk_pllv3(clk);
unsigned long parent_rate = clk_get_parent_rate(clk); unsigned long parent_rate = clk_get_parent_rate(clk);
unsigned long min_rate = parent_rate * 54 / 2; unsigned long min_rate;
unsigned long max_rate = parent_rate * 108 / 2; unsigned long max_rate;
u32 val, div; u32 val, div;
if (parent_rate == 0)
return -EINVAL;
min_rate = parent_rate * 54 / 2;
max_rate = parent_rate * 108 / 2;
if (rate < min_rate || rate > max_rate) if (rate < min_rate || rate > max_rate)
return -EINVAL; return -EINVAL;
@ -157,6 +163,9 @@ static ulong clk_pllv3_av_get_rate(struct clk *clk)
u32 div = readl(pll->base) & pll->div_mask; u32 div = readl(pll->base) & pll->div_mask;
u64 temp64 = (u64)parent_rate; u64 temp64 = (u64)parent_rate;
if (mfd == 0)
return -EIO;
temp64 *= mfn; temp64 *= mfn;
do_div(temp64, mfd); do_div(temp64, mfd);
@ -167,13 +176,19 @@ static ulong clk_pllv3_av_set_rate(struct clk *clk, ulong rate)
{ {
struct clk_pllv3 *pll = to_clk_pllv3(clk); struct clk_pllv3 *pll = to_clk_pllv3(clk);
unsigned long parent_rate = clk_get_parent_rate(clk); unsigned long parent_rate = clk_get_parent_rate(clk);
unsigned long min_rate = parent_rate * 27; unsigned long min_rate;
unsigned long max_rate = parent_rate * 54; unsigned long max_rate;
u32 val, div; u32 val, div;
u32 mfn, mfd = 1000000; u32 mfn, mfd = 1000000;
u32 max_mfd = 0x3FFFFFFF; u32 max_mfd = 0x3FFFFFFF;
u64 temp64; u64 temp64;
if (parent_rate == 0)
return -EINVAL;
min_rate = parent_rate * 27;
max_rate = parent_rate * 54;
if (rate < min_rate || rate > max_rate) if (rate < min_rate || rate > max_rate)
return -EINVAL; return -EINVAL;

View file

@ -40,7 +40,7 @@
* the accurate frequency. * the accurate frequency.
*/ */
static ulong mtk_clk_find_parent_rate(struct clk *clk, int id, static ulong mtk_clk_find_parent_rate(struct clk *clk, int id,
const struct driver *drv) const struct driver *drv)
{ {
struct clk parent = { .id = id, }; struct clk parent = { .id = id, };

View file

@ -8,6 +8,10 @@
*/ */
#ifndef __LINUX_CLK_PROVIDER_H #ifndef __LINUX_CLK_PROVIDER_H
#define __LINUX_CLK_PROVIDER_H #define __LINUX_CLK_PROVIDER_H
#include <dm.h>
#include <linux/bitops.h>
#include <linux/err.h>
#include <clk-uclass.h> #include <clk-uclass.h>
static inline void clk_dm(ulong id, struct clk *clk) static inline void clk_dm(ulong id, struct clk *clk)