aboutsummaryrefslogtreecommitdiff
path: root/drivers/clk/imx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/imx')
-rw-r--r--drivers/clk/imx/clk-pllv3.c56
-rw-r--r--drivers/clk/imx/clk.h1
2 files changed, 54 insertions, 3 deletions
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 077757e..fad306a 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -21,19 +21,23 @@
#define UBOOT_DM_CLK_IMX_PLLV3_USB "imx_clk_pllv3_usb"
#define UBOOT_DM_CLK_IMX_PLLV3_AV "imx_clk_pllv3_av"
#define UBOOT_DM_CLK_IMX_PLLV3_ENET "imx_clk_pllv3_enet"
+#define UBOOT_DM_CLK_IMX_PLLV3_GENV2 "imx_clk_pllv3_genericv2"
#define PLL_NUM_OFFSET 0x10
#define PLL_DENOM_OFFSET 0x20
#define BM_PLL_POWER (0x1 << 12)
+#define BM_PLL_POWER_V2 (0x1 << 21)
#define BM_PLL_ENABLE (0x1 << 13)
#define BM_PLL_LOCK (0x1 << 31)
+#define BM_PLL_LOCK_V2 (0x1 << 29)
struct clk_pllv3 {
struct clk clk;
void __iomem *base;
u32 power_bit;
bool powerup_set;
+ u32 lock_bit;
u32 enable_bit;
u32 div_mask;
u32 div_shift;
@@ -42,6 +46,30 @@ struct clk_pllv3 {
#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
+static ulong clk_pllv3_genericv2_get_rate(struct clk *clk)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
+ unsigned long parent_rate = clk_get_parent_rate(clk);
+
+ u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
+
+ return (div == 0) ? parent_rate * 22 : parent_rate * 20;
+}
+
+static ulong clk_pllv3_genericv2_set_rate(struct clk *clk, ulong rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(clk);
+ unsigned long parent_rate = clk_get_parent_rate(clk);
+
+ u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
+ u32 val = (div == 0) ? parent_rate * 22 : parent_rate * 20;
+
+ if (rate == val)
+ return 0;
+
+ return -EINVAL;
+}
+
static ulong clk_pllv3_generic_get_rate(struct clk *clk)
{
struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
@@ -71,7 +99,7 @@ static ulong clk_pllv3_generic_set_rate(struct clk *clk, ulong rate)
writel(val, pll->base);
/* Wait for PLL to lock */
- while (!(readl(pll->base) & BM_PLL_LOCK))
+ while (!(readl(pll->base) & pll->lock_bit))
;
return 0;
@@ -120,6 +148,13 @@ static const struct clk_ops clk_pllv3_generic_ops = {
.set_rate = clk_pllv3_generic_set_rate,
};
+static const struct clk_ops clk_pllv3_genericv2_ops = {
+ .get_rate = clk_pllv3_genericv2_get_rate,
+ .enable = clk_pllv3_generic_enable,
+ .disable = clk_pllv3_generic_disable,
+ .set_rate = clk_pllv3_genericv2_set_rate,
+};
+
static ulong clk_pllv3_sys_get_rate(struct clk *clk)
{
struct clk_pllv3 *pll = to_clk_pllv3(clk);
@@ -153,7 +188,7 @@ static ulong clk_pllv3_sys_set_rate(struct clk *clk, ulong rate)
writel(val, pll->base);
/* Wait for PLL to lock */
- while (!(readl(pll->base) & BM_PLL_LOCK))
+ while (!(readl(pll->base) & pll->lock_bit))
;
return 0;
@@ -221,7 +256,7 @@ static ulong clk_pllv3_av_set_rate(struct clk *clk, ulong rate)
writel(mfd, pll->base + PLL_DENOM_OFFSET);
/* Wait for PLL to lock */
- while (!(readl(pll->base) & BM_PLL_LOCK))
+ while (!(readl(pll->base) & pll->lock_bit))
;
return 0;
@@ -262,6 +297,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
pll->power_bit = BM_PLL_POWER;
pll->enable_bit = BM_PLL_ENABLE;
+ pll->lock_bit = BM_PLL_LOCK;
switch (type) {
case IMX_PLLV3_GENERIC:
@@ -269,6 +305,13 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
pll->div_shift = 0;
pll->powerup_set = false;
break;
+ case IMX_PLLV3_GENERICV2:
+ pll->power_bit = BM_PLL_POWER_V2;
+ pll->lock_bit = BM_PLL_LOCK_V2;
+ drv_name = UBOOT_DM_CLK_IMX_PLLV3_GENV2;
+ pll->div_shift = 0;
+ pll->powerup_set = false;
+ break;
case IMX_PLLV3_SYS:
drv_name = UBOOT_DM_CLK_IMX_PLLV3_SYS;
pll->div_shift = 0;
@@ -313,6 +356,13 @@ U_BOOT_DRIVER(clk_pllv3_generic) = {
.flags = DM_FLAG_PRE_RELOC,
};
+U_BOOT_DRIVER(clk_pllv3_genericv2) = {
+ .name = UBOOT_DM_CLK_IMX_PLLV3_GENV2,
+ .id = UCLASS_CLK,
+ .ops = &clk_pllv3_genericv2_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
U_BOOT_DRIVER(clk_pllv3_sys) = {
.name = UBOOT_DM_CLK_IMX_PLLV3_SYS,
.id = UCLASS_CLK,
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 0e1eaf0..46dee35 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -10,6 +10,7 @@
enum imx_pllv3_type {
IMX_PLLV3_GENERIC,
+ IMX_PLLV3_GENERICV2,
IMX_PLLV3_SYS,
IMX_PLLV3_USB,
IMX_PLLV3_USB_VF610,