* [PATCH 01/17] clk: divider: Add onebased divider support
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 02/17] clk: gate: Add inverted gate support Sascha Hauer
` (15 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
In some dividers the register value matches the divider value. This
patch adds support for them.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/clk-divider.c | 44 ++++++++++++++++++++++++++++++++------------
include/linux/clk.h | 15 +++++++++++++++
2 files changed, 47 insertions(+), 12 deletions(-)
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 58a7ea5..3bf8105 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -20,13 +20,12 @@
#include <linux/clk.h>
#include <linux/err.h>
-struct clk_divider {
- struct clk clk;
- u8 shift;
- u8 width;
- void __iomem *reg;
- const char *parent;
-};
+static unsigned int clk_divider_maxdiv(struct clk_divider *div)
+{
+ if (div->flags & CLK_DIVIDER_ONE_BASED)
+ return (1 << div->width) - 1;
+ return 1 << div->width;
+}
static int clk_divider_set_rate(struct clk *clk, unsigned long rate,
unsigned long parent_rate)
@@ -40,11 +39,11 @@ static int clk_divider_set_rate(struct clk *clk, unsigned long rate,
rate = 1;
divval = DIV_ROUND_UP(parent_rate, rate);
+ if (divval > clk_divider_maxdiv(div))
+ divval = clk_divider_maxdiv(div);
- if (divval > (1 << div->width))
- divval = 1 << (div->width);
-
- divval--;
+ if (!(div->flags & CLK_DIVIDER_ONE_BASED))
+ divval--;
val = readl(div->reg);
val &= ~(((1 << div->width) - 1) << div->shift);
@@ -63,7 +62,12 @@ static unsigned long clk_divider_recalc_rate(struct clk *clk,
val = readl(div->reg) >> div->shift;
val &= (1 << div->width) - 1;
- val++;
+ if (div->flags & CLK_DIVIDER_ONE_BASED) {
+ if (!val)
+ val++;
+ } else {
+ val++;
+ }
return parent_rate / val;
}
@@ -96,3 +100,19 @@ struct clk *clk_divider(const char *name, const char *parent,
return &div->clk;
}
+
+struct clk *clk_divider_one_based(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width)
+{
+ struct clk_divider *div;
+ struct clk *clk;
+
+ clk = clk_divider(name, parent, reg, shift, width);
+ if (IS_ERR(clk))
+ return clk;
+
+ div = container_of(clk, struct clk_divider, clk);
+ div->flags |= CLK_DIVIDER_ONE_BASED;
+
+ return clk;
+}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 37a4813..9c41cb8 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -188,8 +188,23 @@ struct clk_div_table {
};
struct clk *clk_fixed(const char *name, int rate);
+
+struct clk_divider {
+ struct clk clk;
+ u8 shift;
+ u8 width;
+ void __iomem *reg;
+ const char *parent;
+#define CLK_DIVIDER_ONE_BASED (1 << 0)
+ unsigned flags;
+};
+
+extern struct clk_ops clk_divider_ops;
+
struct clk *clk_divider(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width);
+struct clk *clk_divider_one_based(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width);
struct clk *clk_divider_table(const char *name,
const char *parent, void __iomem *reg, u8 shift, u8 width,
const struct clk_div_table *table);
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 02/17] clk: gate: Add inverted gate support
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
2013-06-20 6:54 ` [PATCH 01/17] clk: divider: Add onebased divider support Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 03/17] clk: add prototype for clk_is_enabled Sascha Hauer
` (14 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
This adds support for gates which need 0 to enable.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/clk-gate.c | 37 +++++++++++++++++++++++++++++++++----
include/linux/clk.h | 2 ++
2 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index a455094..f632d85 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -25,6 +25,8 @@ struct clk_gate {
void __iomem *reg;
int shift;
const char *parent;
+#define CLK_GATE_INVERTED (1 << 0)
+ unsigned flags;
};
static int clk_gate_enable(struct clk *clk)
@@ -33,7 +35,12 @@ static int clk_gate_enable(struct clk *clk)
u32 val;
val = readl(g->reg);
- val |= 1 << g->shift;
+
+ if (g->flags & CLK_GATE_INVERTED)
+ val &= ~(1 << g->shift);
+ else
+ val |= 1 << g->shift;
+
writel(val, g->reg);
return 0;
@@ -45,7 +52,12 @@ static void clk_gate_disable(struct clk *clk)
u32 val;
val = readl(g->reg);
- val &= ~(1 << g->shift);
+
+ if (g->flags & CLK_GATE_INVERTED)
+ val |= 1 << g->shift;
+ else
+ val &= ~(1 << g->shift);
+
writel(val, g->reg);
}
@@ -57,9 +69,9 @@ static int clk_gate_is_enabled(struct clk *clk)
val = readl(g->reg);
if (val & (1 << g->shift))
- return 1;
+ return g->flags & CLK_GATE_INVERTED ? 0 : 1;
else
- return 0;
+ return g->flags & CLK_GATE_INVERTED ? 1 : 0;
}
struct clk_ops clk_gate_ops = {
@@ -90,3 +102,20 @@ struct clk *clk_gate(const char *name, const char *parent, void __iomem *reg,
return &g->clk;
}
+
+struct clk *clk_gate_inverted(const char *name, const char *parent,
+ void __iomem *reg, u8 shift)
+{
+ struct clk *clk;
+ struct clk_gate *g;
+
+ clk = clk_gate(name, parent, reg, shift);
+ if (IS_ERR(clk))
+ return clk;
+
+ g = container_of(clk, struct clk_gate, clk);
+
+ g->flags = CLK_GATE_INVERTED;
+
+ return clk;
+}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 9c41cb8..718faa0 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -214,6 +214,8 @@ struct clk *clk_mux(const char *name, void __iomem *reg,
u8 shift, u8 width, const char **parents, u8 num_parents);
struct clk *clk_gate(const char *name, const char *parent, void __iomem *reg,
u8 shift);
+struct clk *clk_gate_inverted(const char *name, const char *parent, void __iomem *reg,
+ u8 shift);
int clk_is_enabled_always(struct clk *clk);
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 03/17] clk: add prototype for clk_is_enabled
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
2013-06-20 6:54 ` [PATCH 01/17] clk: divider: Add onebased divider support Sascha Hauer
2013-06-20 6:54 ` [PATCH 02/17] clk: gate: Add inverted gate support Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 04/17] ARM: MXS: Add MXS specific clk types Sascha Hauer
` (13 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
On MXS we need to poll the busy bit when changing a clock rate, but only
when the parent clocks are enabled. This exposes the already present
function clk_is_enabled which is suitable for this job.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/clk.c | 2 +-
include/linux/clk.h | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index a3def53..690a0c6 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -208,7 +208,7 @@ int clk_register(struct clk *clk)
return 0;
}
-static int clk_is_enabled(struct clk *clk)
+int clk_is_enabled(struct clk *clk)
{
int enabled;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 718faa0..38832ba 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -216,6 +216,7 @@ struct clk *clk_gate(const char *name, const char *parent, void __iomem *reg,
u8 shift);
struct clk *clk_gate_inverted(const char *name, const char *parent, void __iomem *reg,
u8 shift);
+int clk_is_enabled(struct clk *clk);
int clk_is_enabled_always(struct clk *clk);
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 04/17] ARM: MXS: Add MXS specific clk types
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (2 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 03/17] clk: add prototype for clk_is_enabled Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-21 12:14 ` Jürgen Beisert
2013-06-20 6:54 ` [PATCH 05/17] ARM: MXS: add clk drivers Sascha Hauer
` (12 subsequent siblings)
16 siblings, 1 reply; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
MXS needs some special MXS specific clock types:
- pll
- ref (fractional divider)
- busy divider (divider with additional busy bit to poll on a rate change)
- lcdif (Combined clock out of a fractional divider, a divider and a gate.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/Kconfig | 2 +
drivers/clk/Makefile | 2 +
drivers/clk/mxs/Makefile | 2 +
drivers/clk/mxs/clk-div.c | 112 ++++++++++++++++++++++++++++++++
drivers/clk/mxs/clk-frac.c | 136 +++++++++++++++++++++++++++++++++++++++
drivers/clk/mxs/clk-lcdif.c | 75 ++++++++++++++++++++++
drivers/clk/mxs/clk-pll.c | 117 ++++++++++++++++++++++++++++++++++
drivers/clk/mxs/clk-ref.c | 152 ++++++++++++++++++++++++++++++++++++++++++++
drivers/clk/mxs/clk.h | 52 +++++++++++++++
9 files changed, 650 insertions(+)
create mode 100644 drivers/clk/mxs/Makefile
create mode 100644 drivers/clk/mxs/clk-div.c
create mode 100644 drivers/clk/mxs/clk-frac.c
create mode 100644 drivers/clk/mxs/clk-lcdif.c
create mode 100644 drivers/clk/mxs/clk-pll.c
create mode 100644 drivers/clk/mxs/clk-ref.c
create mode 100644 drivers/clk/mxs/clk.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index cfb82b0..af5d8cd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -88,6 +88,8 @@ config ARCH_MVEBU
config ARCH_MXS
bool "Freescale i.MX23/28 (mxs) based"
select GENERIC_GPIO
+ select COMMON_CLK
+ select CLKDEV_LOOKUP
config ARCH_NETX
bool "Hilscher NetX based"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 656b859..d6c923d 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,3 +1,5 @@
obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed.o clk-divider.o clk-fixed-factor.o \
clk-mux.o clk-gate.o clk-divider-table.o
obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
+
+obj-$(CONFIG_ARCH_MXS) += mxs/
diff --git a/drivers/clk/mxs/Makefile b/drivers/clk/mxs/Makefile
new file mode 100644
index 0000000..8b1173d
--- /dev/null
+++ b/drivers/clk/mxs/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARCH_MXS) += clk-ref.o clk-pll.o clk-frac.o clk-div.o
+obj-$(CONFIG_DRIVER_VIDEO_STM) += clk-lcdif.o
diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c
new file mode 100644
index 0000000..e8dae25
--- /dev/null
+++ b/drivers/clk/mxs/clk-div.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <common.h>
+#include <io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include "clk.h"
+
+/**
+ * struct clk_div - mxs integer divider clock
+ * @divider: the parent class
+ * @ops: pointer to clk_ops of parent class
+ * @reg: register address
+ * @busy: busy bit shift
+ *
+ * The mxs divider clock is a subclass of basic clk_divider with an
+ * addtional busy bit.
+ */
+struct clk_div {
+ struct clk_divider divider;
+ const char *parent;
+ const struct clk_ops *ops;
+ void __iomem *reg;
+ u8 busy;
+};
+
+static inline struct clk_div *to_clk_div(struct clk *clk)
+{
+ struct clk_divider *divider = container_of(clk, struct clk_divider, clk);
+
+ return container_of(divider, struct clk_div, divider);
+}
+
+static unsigned long clk_div_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ struct clk_div *div = to_clk_div(clk);
+
+ return div->ops->recalc_rate(&div->divider.clk, parent_rate);
+}
+
+static long clk_div_round_rate(struct clk *clk, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_div *div = to_clk_div(clk);
+
+ return div->ops->round_rate(&div->divider.clk, rate, prate);
+}
+
+static int clk_div_set_rate(struct clk *clk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_div *div = to_clk_div(clk);
+ int ret;
+
+ ret = div->ops->set_rate(&div->divider.clk, rate, parent_rate);
+ if (ret)
+ return ret;
+
+ if (clk_is_enabled(clk))
+ while (readl(div->reg) & 1 << div->busy);
+
+ return 0;
+}
+
+static struct clk_ops clk_div_ops = {
+ .recalc_rate = clk_div_recalc_rate,
+ .round_rate = clk_div_round_rate,
+ .set_rate = clk_div_set_rate,
+};
+
+struct clk *mxs_clk_div(const char *name, const char *parent_name,
+ void __iomem *reg, u8 shift, u8 width, u8 busy)
+{
+ struct clk_div *div;
+ int ret;
+
+ div = xzalloc(sizeof(*div));
+ if (!div)
+ return ERR_PTR(-ENOMEM);
+
+ div->parent = parent_name;
+ div->divider.clk.name = name;
+ div->divider.clk.ops = &clk_div_ops;
+ div->divider.clk.parent_names = &div->parent;
+ div->divider.clk.num_parents = 1;
+
+ div->reg = reg;
+ div->busy = busy;
+
+ div->divider.reg = reg;
+ div->divider.shift = shift;
+ div->divider.width = width;
+ div->divider.flags = CLK_DIVIDER_ONE_BASED;
+ div->ops = &clk_divider_ops;
+
+ ret = clk_register(&div->divider.clk);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return &div->divider.clk;
+}
diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c
new file mode 100644
index 0000000..7aa8504
--- /dev/null
+++ b/drivers/clk/mxs/clk-frac.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <common.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <io.h>
+#include <asm-generic/div64.h>
+
+#include "clk.h"
+
+/**
+ * struct clk_frac - mxs fractional divider clock
+ * @hw: clk_hw for the fractional divider clock
+ * @reg: register address
+ * @shift: the divider bit shift
+ * @width: the divider bit width
+ * @busy: busy bit shift
+ *
+ * The clock is an adjustable fractional divider with a busy bit to wait
+ * when the divider is adjusted.
+ */
+struct clk_frac {
+ struct clk clk;
+ const char *parent;
+ void __iomem *reg;
+ u8 shift;
+ u8 width;
+ u8 busy;
+};
+
+#define to_clk_frac(_hw) container_of(_hw, struct clk_frac, clk)
+
+static unsigned long clk_frac_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ struct clk_frac *frac = to_clk_frac(clk);
+ u32 div;
+
+ div = readl(frac->reg) >> frac->shift;
+ div &= (1 << frac->width) - 1;
+
+ return (parent_rate >> frac->width) * div;
+}
+
+static long clk_frac_round_rate(struct clk *clk, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_frac *frac = to_clk_frac(clk);
+ unsigned long parent_rate = *prate;
+ u32 div;
+ u64 tmp;
+
+ if (rate > parent_rate)
+ return -EINVAL;
+
+ tmp = rate;
+ tmp <<= frac->width;
+ do_div(tmp, parent_rate);
+ div = tmp;
+
+ if (!div)
+ return -EINVAL;
+
+ return (parent_rate >> frac->width) * div;
+}
+
+static int clk_frac_set_rate(struct clk *clk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_frac *frac = to_clk_frac(clk);
+ u32 div, val;
+ u64 tmp;
+
+ if (rate > parent_rate)
+ return -EINVAL;
+
+ tmp = rate;
+ tmp <<= frac->width;
+ do_div(tmp, parent_rate);
+ div = tmp;
+
+ if (!div)
+ return -EINVAL;
+
+ val = readl(frac->reg);
+ val &= ~(((1 << frac->width) - 1) << frac->shift);
+ val |= div << frac->shift;
+ writel(val, frac->reg);
+
+ if (clk_is_enabled(clk))
+ while (readl(frac->reg) & 1 << frac->busy);
+
+ return 0;
+}
+
+static struct clk_ops clk_frac_ops = {
+ .recalc_rate = clk_frac_recalc_rate,
+ .round_rate = clk_frac_round_rate,
+ .set_rate = clk_frac_set_rate,
+};
+
+struct clk *mxs_clk_frac(const char *name, const char *parent_name,
+ void __iomem *reg, u8 shift, u8 width, u8 busy)
+{
+ struct clk_frac *frac;
+ int ret;
+
+ frac = kzalloc(sizeof(*frac), GFP_KERNEL);
+ if (!frac)
+ return ERR_PTR(-ENOMEM);
+
+ frac->parent = parent_name;
+ frac->clk.name = name;
+ frac->clk.ops = &clk_frac_ops;
+ frac->clk.parent_names = &frac->parent;
+ frac->clk.num_parents = 1;
+
+ frac->reg = reg;
+ frac->shift = shift;
+ frac->width = width;
+
+ ret = clk_register(&frac->clk);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return &frac->clk;
+}
diff --git a/drivers/clk/mxs/clk-lcdif.c b/drivers/clk/mxs/clk-lcdif.c
new file mode 100644
index 0000000..86dfe89
--- /dev/null
+++ b/drivers/clk/mxs/clk-lcdif.c
@@ -0,0 +1,75 @@
+#include <common.h>
+#include <io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include "clk.h"
+
+struct clk_lcdif {
+ struct clk clk;
+
+ struct clk *frac, *div, *gate;
+ const char *parent;
+};
+
+#define to_clk_lcdif(_hw) container_of(_hw, struct clk_lcdif, clk)
+
+static int clk_lcdif_set_rate(struct clk *clk, unsigned long rate,
+ unsigned long unused)
+{
+ struct clk_lcdif *lcdif = to_clk_lcdif(clk);
+ unsigned long frac, div, best_div = 1;
+ int delta, best_delta = 0x7fffffff;
+ unsigned long frate, rrate, best_frate;
+ unsigned long parent_rate = clk_get_rate(clk_get_parent(lcdif->frac));
+
+ best_frate = parent_rate;
+
+ for (frac = 18; frac < 35; frac++) {
+ frate = (parent_rate / frac) * 18;
+ div = frate / rate;
+ if (!div)
+ div = 1;
+ rrate = frate / div;
+ delta = rate - rrate;
+ if (abs(delta) < abs(best_delta)) {
+ best_frate = frate;
+ best_div = div;
+ best_delta = delta;
+ }
+ }
+
+ clk_set_rate(lcdif->frac, best_frate);
+ best_frate = clk_get_rate(lcdif->frac);
+ clk_set_rate(lcdif->div, (best_frate + best_div) / best_div);
+
+ return 0;
+}
+
+static const struct clk_ops clk_lcdif_ops = {
+ .set_rate = clk_lcdif_set_rate,
+};
+
+struct clk *mxs_clk_lcdif(const char *name, struct clk *frac, struct clk *div,
+ struct clk *gate)
+{
+ struct clk_lcdif *lcdif;
+ int ret;
+
+ lcdif = xzalloc(sizeof(*lcdif));
+
+ lcdif->parent = gate->name;
+ lcdif->frac = frac;
+ lcdif->div = div;
+ lcdif->gate = gate;
+ lcdif->clk.name = name;
+ lcdif->clk.ops = &clk_lcdif_ops;
+ lcdif->clk.parent_names = &lcdif->parent;
+ lcdif->clk.num_parents = 1;
+
+ ret = clk_register(&lcdif->clk);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return &lcdif->clk;
+}
diff --git a/drivers/clk/mxs/clk-pll.c b/drivers/clk/mxs/clk-pll.c
new file mode 100644
index 0000000..89fd6b5
--- /dev/null
+++ b/drivers/clk/mxs/clk-pll.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <common.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <io.h>
+
+#include "clk.h"
+
+#define SET 0x4
+#define CLR 0x8
+
+/**
+ * struct clk_pll - mxs pll clock
+ * @hw: clk_hw for the pll
+ * @base: base address of the pll
+ * @power: the shift of power bit
+ * @rate: the clock rate of the pll
+ *
+ * The mxs pll is a fixed rate clock with power and gate control,
+ * and the shift of gate bit is always 31.
+ */
+struct clk_pll {
+ struct clk clk;
+ const char *parent;
+ void __iomem *base;
+ u8 power;
+ unsigned long rate;
+};
+
+#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, clk)
+
+static int clk_pll_enable(struct clk *clk)
+{
+ struct clk_pll *pll = to_clk_pll(clk);
+
+ writel(1 << pll->power, pll->base + SET);
+
+ udelay(10);
+
+ writel(1 << 31, pll->base + CLR);
+
+ return 0;
+}
+
+static void clk_pll_disable(struct clk *clk)
+{
+ struct clk_pll *pll = to_clk_pll(clk);
+
+ writel(1 << 31, pll->base + SET);
+
+ writel(1 << pll->power, pll->base + CLR);
+}
+
+static int clk_pll_is_enabled(struct clk *clk)
+{
+ struct clk_pll *pll = to_clk_pll(clk);
+ u32 val;
+
+ val = readl(pll->base);
+
+ if (val & (1 << 31))
+ return 0;
+ else
+ return 1;
+}
+
+static unsigned long clk_pll_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ struct clk_pll *pll = to_clk_pll(clk);
+
+ return pll->rate;
+}
+
+static const struct clk_ops clk_pll_ops = {
+ .enable = clk_pll_enable,
+ .disable = clk_pll_disable,
+ .recalc_rate = clk_pll_recalc_rate,
+ .is_enabled = clk_pll_is_enabled,
+};
+
+struct clk *mxs_clk_pll(const char *name, const char *parent_name,
+ void __iomem *base, u8 power, unsigned long rate)
+{
+ struct clk_pll *pll;
+ int ret;
+
+ pll = xzalloc(sizeof(*pll));
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->parent = parent_name;
+ pll->clk.name = name;
+ pll->clk.ops = &clk_pll_ops;
+ pll->clk.parent_names = &pll->parent;
+ pll->clk.num_parents = 1;
+
+ pll->base = base;
+ pll->rate = rate;
+ pll->power = power;
+
+ ret = clk_register(&pll->clk);
+ if (ret)
+ ERR_PTR(ret);
+
+ return &pll->clk;
+}
diff --git a/drivers/clk/mxs/clk-ref.c b/drivers/clk/mxs/clk-ref.c
new file mode 100644
index 0000000..d62ebfc
--- /dev/null
+++ b/drivers/clk/mxs/clk-ref.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <common.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <io.h>
+#include <asm-generic/div64.h>
+
+#include "clk.h"
+
+/**
+ * struct clk_ref - mxs reference clock
+ * @hw: clk_hw for the reference clock
+ * @reg: register address
+ * @idx: the index of the reference clock within the same register
+ *
+ * The mxs reference clock sources from pll. Every 4 reference clocks share
+ * one register space, and @idx is used to identify them. Each reference
+ * clock has a gate control and a fractional * divider. The rate is calculated
+ * as pll rate * (18 / FRAC), where FRAC = 18 ~ 35.
+ */
+struct clk_ref {
+ struct clk clk;
+ const char *parent;
+ void __iomem *reg;
+ u8 idx;
+};
+
+#define to_clk_ref(_hw) container_of(_hw, struct clk_ref, clk)
+
+#define SET 0x4
+#define CLR 0x8
+
+static int clk_ref_enable(struct clk *clk)
+{
+ struct clk_ref *ref = to_clk_ref(clk);
+
+ writel(1 << ((ref->idx + 1) * 8 - 1), ref->reg + CLR);
+
+ return 0;
+}
+
+static void clk_ref_disable(struct clk *clk)
+{
+ struct clk_ref *ref = to_clk_ref(clk);
+
+ writel(1 << ((ref->idx + 1) * 8 - 1), ref->reg + SET);
+}
+
+static unsigned long clk_ref_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ struct clk_ref *ref = to_clk_ref(clk);
+ u64 tmp = parent_rate;
+ u8 frac = (readl(ref->reg) >> (ref->idx * 8)) & 0x3f;
+
+ tmp *= 18;
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static long clk_ref_round_rate(struct clk *clk, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+ u64 tmp = parent_rate;
+ u32 frac;
+
+ tmp = tmp * 18 + rate / 2;
+ do_div(tmp, rate);
+ frac = tmp;
+
+ if (frac < 18)
+ frac = 18;
+ else if (frac > 35)
+ frac = 35;
+
+ tmp = parent_rate;
+ tmp *= 18;
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static int clk_ref_set_rate(struct clk *clk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_ref *ref = to_clk_ref(clk);
+ u64 tmp = parent_rate;
+ u32 val;
+ u32 frac, shift = ref->idx * 8;
+
+ tmp = tmp * 18 + rate / 2;
+ do_div(tmp, rate);
+ frac = tmp;
+
+ if (frac < 18)
+ frac = 18;
+ else if (frac > 35)
+ frac = 35;
+
+ val = readl(ref->reg);
+ val &= ~(0x3f << shift);
+ val |= frac << shift;
+ writel(val, ref->reg);
+
+ return 0;
+}
+
+static const struct clk_ops clk_ref_ops = {
+ .enable = clk_ref_enable,
+ .disable = clk_ref_disable,
+ .recalc_rate = clk_ref_recalc_rate,
+ .round_rate = clk_ref_round_rate,
+ .set_rate = clk_ref_set_rate,
+};
+
+struct clk *mxs_clk_ref(const char *name, const char *parent_name,
+ void __iomem *reg, u8 idx)
+{
+ struct clk_ref *ref;
+ int ret;
+
+ ref = xzalloc(sizeof(*ref));
+ if (!ref)
+ return ERR_PTR(-ENOMEM);
+
+ ref->parent = parent_name;
+ ref->clk.name = name;
+ ref->clk.ops = &clk_ref_ops;
+ ref->clk.parent_names = &ref->parent;
+ ref->clk.num_parents = 1;
+
+ ref->reg = reg;
+ ref->idx = idx;
+
+ ret = clk_register(&ref->clk);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return &ref->clk;
+}
diff --git a/drivers/clk/mxs/clk.h b/drivers/clk/mxs/clk.h
new file mode 100644
index 0000000..b4fcfa0
--- /dev/null
+++ b/drivers/clk/mxs/clk.h
@@ -0,0 +1,52 @@
+#ifndef __MXS_CLK_H
+#define __MXS_CLK_H
+
+int mxs_clk_wait(void __iomem *reg, u8 shift);
+
+struct clk *mxs_clk_pll(const char *name, const char *parent_name,
+ void __iomem *base, u8 power, unsigned long rate);
+
+struct clk *mxs_clk_ref(const char *name, const char *parent_name,
+ void __iomem *reg, u8 idx);
+
+struct clk *mxs_clk_div(const char *name, const char *parent_name,
+ void __iomem *reg, u8 shift, u8 width, u8 busy);
+
+struct clk *mxs_clk_frac(const char *name, const char *parent_name,
+ void __iomem *reg, u8 shift, u8 width, u8 busy);
+
+#ifdef CONFIG_DRIVER_VIDEO_STM
+struct clk *mxs_clk_lcdif(const char *name, struct clk *frac, struct clk *div,
+ struct clk *gate);
+#else
+static inline struct clk *mxs_clk_lcdif(const char *name, struct clk *frac, struct clk *div,
+ struct clk *gate)
+{
+ return ERR_PTR(-ENOSYS);
+}
+#endif
+
+static inline struct clk *mxs_clk_fixed(const char *name, int rate)
+{
+ return clk_fixed(name, rate);
+}
+
+static inline struct clk *mxs_clk_gate(const char *name,
+ const char *parent_name, void __iomem *reg, u8 shift)
+{
+ return clk_gate_inverted(name, parent_name, reg, shift);
+}
+
+static inline struct clk *mxs_clk_mux(const char *name, void __iomem *reg,
+ u8 shift, u8 width, const char **parent_names, int num_parents)
+{
+ return clk_mux(name, reg, shift, width, parent_names, num_parents);
+}
+
+static inline struct clk *mxs_clk_fixed_factor(const char *name,
+ const char *parent_name, unsigned int mult, unsigned int div)
+{
+ return clk_fixed_factor(name, parent_name, mult, div);
+}
+
+#endif /* __MXS_CLK_H */
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 04/17] ARM: MXS: Add MXS specific clk types
2013-06-20 6:54 ` [PATCH 04/17] ARM: MXS: Add MXS specific clk types Sascha Hauer
@ 2013-06-21 12:14 ` Jürgen Beisert
0 siblings, 0 replies; 19+ messages in thread
From: Jürgen Beisert @ 2013-06-21 12:14 UTC (permalink / raw)
To: barebox
With the following patch on top of [PATCH 04/17]:
diff --git a/drivers/clk/mxs/clk-ref.c b/drivers/clk/mxs/clk-ref.c
index d62ebfc..7ff5527 100644
--- a/drivers/clk/mxs/clk-ref.c
+++ b/drivers/clk/mxs/clk-ref.c
@@ -40,6 +40,17 @@ struct clk_ref {
#define SET 0x4
#define CLR 0x8
+static int clk_ref_is_enabled(struct clk *clk)
+{
+ struct clk_ref *ref = to_clk_ref(clk);
+ u32 reg = readl(ref->reg);
+
+ if (reg & 1 << ((ref->idx + 1) * 8 - 1))
+ return 0;
+
+ return 1;
+}
+
static int clk_ref_enable(struct clk *clk)
{
struct clk_ref *ref = to_clk_ref(clk);
@@ -118,6 +129,7 @@ static int clk_ref_set_rate(struct clk *clk, unsigned long rate,
}
static const struct clk_ops clk_ref_ops = {
+ .is_enabled = clk_ref_is_enabled,
.enable = clk_ref_enable,
.disable = clk_ref_disable,
.recalc_rate = clk_ref_recalc_rate,
...I get the expected output at runtime (e.g. CPU and EMI clocks get
reported as 'enabled'):
luma:/ clk_dump
ref_xtal (rate 24000000, enabled)
pll (rate 480000000, enabled)
ref_cpu (rate 454736842, enabled) <---------
cpu_pll (rate 454736842, enabled)
cpu (rate 454736842, enabled)
hbus (rate 151578947, enabled)
ref_emi (rate 261818181, enabled) <---------
emi_pll (rate 130909090, enabled)
emi_sel (rate 130909090, enabled)
emi (rate 130909090, enabled)
ref_pix (rate 480000000, disabled)
lcdif_sel (rate 480000000, disabled)
lcdif_div (rate 480000000, disabled)
lcdif (rate 480000000, disabled)
ref_io (rate 480000000, enabled)
ssp_sel (rate 480000000, enabled)
ssp_div (rate 96000000, enabled)
ssp (rate 96000000, enabled)
spdif_div (rate 120000000, enabled)
spdif (rate 120000000, disabled)
saif_sel (rate 24000000, enabled)
saif_div (rate 366, enabled)
saif (rate 366, disabled)
gpmi_sel (rate 24000000, enabled)
gpmi_div (rate 24000000, enabled)
gpmi (rate 24000000, disabled)
etm_sel (rate 24000000, enabled)
etm_div (rate 24000000, enabled)
etm (rate 24000000, disabled)
cpu_xtal (rate 24000000, enabled)
xbus (rate 24000000, enabled)
emi_xtal (rate 24000000, enabled)
clk32k_div (rate 32000, enabled)
clk32k (rate 32000, enabled)
adc (rate 2000, enabled)
rtc (rate 31250, enabled)
dri (rate 24000000, disabled)
pwm (rate 24000000, disabled)
filt (rate 24000000, disabled)
uart (rate 24000000, enabled)
jbe
--
Pengutronix e.K. | Juergen Beisert |
Linux Solutions for Science and Industry | Phone: +49-5121-206917-5128 |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de/ |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 05/17] ARM: MXS: add clk drivers
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (3 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 04/17] ARM: MXS: Add MXS specific clk types Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 06/17] ARM: MXS: remove board specific clock setups Sascha Hauer
` (11 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
This adds support for the i.MX23 and i.MX28 clock modules. This mostly is
a copy from the kernel.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-mxs/soc-imx23.c | 9 ++
arch/arm/mach-mxs/soc-imx28.c | 9 ++
drivers/clk/mxs/Makefile | 3 +
drivers/clk/mxs/clk-imx23.c | 156 +++++++++++++++++++++++++++++++++
drivers/clk/mxs/clk-imx28.c | 195 ++++++++++++++++++++++++++++++++++++++++++
5 files changed, 372 insertions(+)
create mode 100644 drivers/clk/mxs/clk-imx23.c
create mode 100644 drivers/clk/mxs/clk-imx28.c
diff --git a/arch/arm/mach-mxs/soc-imx23.c b/arch/arm/mach-mxs/soc-imx23.c
index 6819b3c..4e45064 100644
--- a/arch/arm/mach-mxs/soc-imx23.c
+++ b/arch/arm/mach-mxs/soc-imx23.c
@@ -35,3 +35,12 @@ void __noreturn reset_cpu(unsigned long addr)
/*NOTREACHED*/
}
EXPORT_SYMBOL(reset_cpu);
+
+static int imx23_devices_init(void)
+{
+
+ add_generic_device("imx23-clkctrl", 0, NULL, IMX_CCM_BASE, 0x100, IORESOURCE_MEM, NULL);
+
+ return 0;
+}
+postcore_initcall(imx23_devices_init);
diff --git a/arch/arm/mach-mxs/soc-imx28.c b/arch/arm/mach-mxs/soc-imx28.c
index ed931af..426f8ac 100644
--- a/arch/arm/mach-mxs/soc-imx28.c
+++ b/arch/arm/mach-mxs/soc-imx28.c
@@ -53,3 +53,12 @@ static int imx28_init(void)
return 0;
}
postcore_initcall(imx28_init);
+
+static int imx28_devices_init(void)
+{
+
+ add_generic_device("imx28-clkctrl", 0, NULL, IMX_CCM_BASE, 0x100, IORESOURCE_MEM, NULL);
+
+ return 0;
+}
+postcore_initcall(imx28_devices_init);
diff --git a/drivers/clk/mxs/Makefile b/drivers/clk/mxs/Makefile
index 8b1173d..fb4e5db 100644
--- a/drivers/clk/mxs/Makefile
+++ b/drivers/clk/mxs/Makefile
@@ -1,2 +1,5 @@
obj-$(CONFIG_ARCH_MXS) += clk-ref.o clk-pll.o clk-frac.o clk-div.o
obj-$(CONFIG_DRIVER_VIDEO_STM) += clk-lcdif.o
+
+obj-$(CONFIG_ARCH_IMX23) += clk-imx23.o
+obj-$(CONFIG_ARCH_IMX28) += clk-imx28.o
diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c
new file mode 100644
index 0000000..4b15350
--- /dev/null
+++ b/drivers/clk/mxs/clk-imx23.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx-regs.h>
+
+#include "clk.h"
+
+#define PLLCTRL0 (regs + 0x0000)
+#define CPU (regs + 0x0020)
+#define HBUS (regs + 0x0030)
+#define XBUS (regs + 0x0040)
+#define XTAL (regs + 0x0050)
+#define PIX (regs + 0x0060)
+#define SSP (regs + 0x0070)
+#define GPMI (regs + 0x0080)
+#define SPDIF (regs + 0x0090)
+#define EMI (regs + 0x00a0)
+#define SAIF (regs + 0x00c0)
+#define TV (regs + 0x00d0)
+#define ETM (regs + 0x00e0)
+#define FRAC (regs + 0x00f0)
+#define CLKSEQ (regs + 0x0110)
+
+static const char *sel_pll[] = { "pll", "ref_xtal", };
+static const char *sel_cpu[] = { "ref_cpu", "ref_xtal", };
+static const char *sel_pix[] = { "ref_pix", "ref_xtal", };
+static const char *sel_io[] = { "ref_io", "ref_xtal", };
+static const char *cpu_sels[] = { "cpu_pll", "cpu_xtal", };
+static const char *emi_sels[] = { "emi_pll", "emi_xtal", };
+
+enum imx23_clk {
+ ref_xtal, pll, ref_cpu, ref_emi, ref_pix, ref_io, saif_sel,
+ lcdif_sel, gpmi_sel, ssp_sel, emi_sel, cpu, etm_sel, cpu_pll,
+ cpu_xtal, hbus, xbus, lcdif_div, ssp_div, gpmi_div, emi_pll,
+ emi_xtal, etm_div, saif_div, clk32k_div, rtc, adc, spdif_div,
+ clk32k, dri, pwm, filt, uart, ssp, gpmi, spdif, emi, saif,
+ lcdif, etm, usb, usb_phy, lcdif_comp,
+ clk_max
+};
+
+static struct clk *clks[clk_max];
+
+int __init mx23_clocks_init(void __iomem *regs)
+{
+ clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
+ clks[pll] = mxs_clk_pll("pll", "ref_xtal", PLLCTRL0, 16, 480000000);
+ clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll", FRAC, 0);
+ clks[ref_emi] = mxs_clk_ref("ref_emi", "pll", FRAC, 1);
+ clks[ref_pix] = mxs_clk_ref("ref_pix", "pll", FRAC, 2);
+ clks[ref_io] = mxs_clk_ref("ref_io", "pll", FRAC, 3);
+ clks[saif_sel] = mxs_clk_mux("saif_sel", CLKSEQ, 0, 1, sel_pll, ARRAY_SIZE(sel_pll));
+ clks[lcdif_sel] = mxs_clk_mux("lcdif_sel", CLKSEQ, 1, 1, sel_pix, ARRAY_SIZE(sel_pix));
+ clks[gpmi_sel] = mxs_clk_mux("gpmi_sel", CLKSEQ, 4, 1, sel_io, ARRAY_SIZE(sel_io));
+ clks[ssp_sel] = mxs_clk_mux("ssp_sel", CLKSEQ, 5, 1, sel_io, ARRAY_SIZE(sel_io));
+ clks[emi_sel] = mxs_clk_mux("emi_sel", CLKSEQ, 6, 1, emi_sels, ARRAY_SIZE(emi_sels));
+ clks[cpu] = mxs_clk_mux("cpu", CLKSEQ, 7, 1, cpu_sels, ARRAY_SIZE(cpu_sels));
+ clks[etm_sel] = mxs_clk_mux("etm_sel", CLKSEQ, 8, 1, sel_cpu, ARRAY_SIZE(sel_cpu));
+ clks[cpu_pll] = mxs_clk_div("cpu_pll", "ref_cpu", CPU, 0, 6, 28);
+ clks[cpu_xtal] = mxs_clk_div("cpu_xtal", "ref_xtal", CPU, 16, 10, 29);
+ clks[hbus] = mxs_clk_div("hbus", "cpu", HBUS, 0, 5, 29);
+ clks[xbus] = mxs_clk_div("xbus", "ref_xtal", XBUS, 0, 10, 31);
+ clks[lcdif_div] = mxs_clk_div("lcdif_div", "lcdif_sel", PIX, 0, 12, 29);
+ clks[ssp_div] = mxs_clk_div("ssp_div", "ssp_sel", SSP, 0, 9, 29);
+ clks[gpmi_div] = mxs_clk_div("gpmi_div", "gpmi_sel", GPMI, 0, 10, 29);
+ clks[emi_pll] = mxs_clk_div("emi_pll", "ref_emi", EMI, 0, 6, 28);
+ clks[emi_xtal] = mxs_clk_div("emi_xtal", "ref_xtal", EMI, 8, 4, 29);
+ clks[etm_div] = mxs_clk_div("etm_div", "etm_sel", ETM, 0, 6, 29);
+ clks[saif_div] = mxs_clk_frac("saif_div", "saif_sel", SAIF, 0, 16, 29);
+ clks[clk32k_div] = mxs_clk_fixed_factor("clk32k_div", "ref_xtal", 1, 750);
+ clks[rtc] = mxs_clk_fixed_factor("rtc", "ref_xtal", 1, 768);
+ clks[adc] = mxs_clk_fixed_factor("adc", "clk32k", 1, 16);
+ clks[spdif_div] = mxs_clk_fixed_factor("spdif_div", "pll", 1, 4);
+ clks[clk32k] = mxs_clk_gate("clk32k", "clk32k_div", XTAL, 26);
+ clks[dri] = mxs_clk_gate("dri", "ref_xtal", XTAL, 28);
+ clks[pwm] = mxs_clk_gate("pwm", "ref_xtal", XTAL, 29);
+ clks[filt] = mxs_clk_gate("filt", "ref_xtal", XTAL, 30);
+ clks[uart] = mxs_clk_gate("uart", "ref_xtal", XTAL, 31);
+ clks[ssp] = mxs_clk_gate("ssp", "ssp_div", SSP, 31);
+ clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
+ clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
+ clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
+ clks[saif] = mxs_clk_gate("saif", "saif_div", SAIF, 31);
+ clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", PIX, 31);
+ clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31);
+ clks[lcdif_comp] = mxs_clk_lcdif("lcdif_comp", clks[ref_pix],
+ clks[lcdif_div], clks[lcdif]);
+
+ clk_set_rate(clks[ref_io], 480000000);
+ clk_set_parent(clks[ssp_sel], clks[ref_io]);
+ clk_set_rate(clks[ssp_div], 96000000);
+ clk_set_parent(clks[lcdif_sel], clks[ref_pix]);
+
+ clkdev_add_physbase(clks[ssp], IMX_SSP1_BASE, NULL);
+ clkdev_add_physbase(clks[ssp], IMX_SSP2_BASE, NULL);
+ clkdev_add_physbase(clks[xbus], IMX_DBGUART_BASE, NULL);
+ clkdev_add_physbase(clks[hbus], IMX_OCOTP_BASE, NULL);
+ clkdev_add_physbase(clks[uart], IMX_UART1_BASE, NULL);
+ clkdev_add_physbase(clks[uart], IMX_UART2_BASE, NULL);
+ clkdev_add_physbase(clks[gpmi], MXS_GPMI_BASE, NULL);
+ if (IS_ENABLED(CONFIG_DRIVER_VIDEO_STM))
+ clkdev_add_physbase(clks[lcdif_comp], IMX_FB_BASE, NULL);
+
+ return 0;
+}
+
+static int imx23_ccm_probe(struct device_d *dev)
+{
+ void __iomem *regs;
+
+ regs = dev_request_mem_region(dev, 0);
+
+ mx23_clocks_init(regs);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx23_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx23-clkctrl",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx23_ccm_driver = {
+ .probe = imx23_ccm_probe,
+ .name = "imx23-clkctrl",
+ .of_compatible = DRV_OF_COMPAT(imx23_ccm_dt_ids),
+};
+
+static int imx23_ccm_init(void)
+{
+ return platform_driver_register(&imx23_ccm_driver);
+}
+postcore_initcall(imx23_ccm_init);
diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c
new file mode 100644
index 0000000..0350aff
--- /dev/null
+++ b/drivers/clk/mxs/clk-imx28.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx-regs.h>
+
+#include "clk.h"
+
+#define PLL0CTRL0 (regs + 0x0000)
+#define PLL1CTRL0 (regs + 0x0020)
+#define PLL2CTRL0 (regs + 0x0040)
+#define CPU (regs + 0x0050)
+#define HBUS (regs + 0x0060)
+#define XBUS (regs + 0x0070)
+#define XTAL (regs + 0x0080)
+#define SSP0 (regs + 0x0090)
+#define SSP1 (regs + 0x00a0)
+#define SSP2 (regs + 0x00b0)
+#define SSP3 (regs + 0x00c0)
+#define GPMI (regs + 0x00d0)
+#define SPDIF (regs + 0x00e0)
+#define EMI (regs + 0x00f0)
+#define SAIF0 (regs + 0x0100)
+#define SAIF1 (regs + 0x0110)
+#define LCDIF (regs + 0x0120)
+#define ETM (regs + 0x0130)
+#define ENET (regs + 0x0140)
+#define FLEXCAN (regs + 0x0160)
+#define FRAC0 (regs + 0x01b0)
+#define FRAC1 (regs + 0x01c0)
+#define CLKSEQ (regs + 0x01d0)
+
+static const char *sel_cpu[] = { "ref_cpu", "ref_xtal", };
+static const char *sel_io0[] = { "ref_io0", "ref_xtal", };
+static const char *sel_io1[] = { "ref_io1", "ref_xtal", };
+static const char *sel_pix[] = { "ref_pix", "ref_xtal", };
+static const char *sel_gpmi[] = { "ref_gpmi", "ref_xtal", };
+static const char *cpu_sels[] = { "cpu_pll", "cpu_xtal", };
+static const char *emi_sels[] = { "emi_pll", "emi_xtal", };
+static const char *ptp_sels[] = { "ref_xtal", "pll0", };
+
+enum imx28_clk {
+ ref_xtal, pll0, pll1, pll2, ref_cpu, ref_emi, ref_io0, ref_io1,
+ ref_pix, ref_hsadc, ref_gpmi, saif0_sel, saif1_sel, gpmi_sel,
+ ssp0_sel, ssp1_sel, ssp2_sel, ssp3_sel, emi_sel, etm_sel,
+ lcdif_sel, cpu, ptp_sel, cpu_pll, cpu_xtal, hbus, xbus,
+ ssp0_div, ssp1_div, ssp2_div, ssp3_div, gpmi_div, emi_pll,
+ emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div,
+ clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0,
+ ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm,
+ fec, can0, can1, usb0, usb1, usb0_phy, usb1_phy, enet_out,
+ lcdif_comp, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+int __init mx28_clocks_init(void __iomem *regs)
+{
+ clks[ref_xtal] = clk_fixed("ref_xtal", 24000000);
+ clks[pll0] = mxs_clk_pll("pll0", "ref_xtal", PLL0CTRL0, 17, 480000000);
+ clks[pll1] = mxs_clk_pll("pll1", "ref_xtal", PLL1CTRL0, 17, 480000000);
+ clks[pll2] = mxs_clk_pll("pll2", "ref_xtal", PLL2CTRL0, 23, 50000000);
+ clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll0", FRAC0, 0);
+ clks[ref_emi] = mxs_clk_ref("ref_emi", "pll0", FRAC0, 1);
+ clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 2);
+ clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 3);
+ clks[ref_pix] = mxs_clk_ref("ref_pix", "pll0", FRAC1, 0);
+ clks[ref_hsadc] = mxs_clk_ref("ref_hsadc", "pll0", FRAC1, 1);
+ clks[ref_gpmi] = mxs_clk_ref("ref_gpmi", "pll0", FRAC1, 2);
+ clks[gpmi_sel] = mxs_clk_mux("gpmi_sel", CLKSEQ, 2, 1, sel_gpmi, ARRAY_SIZE(sel_gpmi));
+ clks[ssp0_sel] = mxs_clk_mux("ssp0_sel", CLKSEQ, 3, 1, sel_io0, ARRAY_SIZE(sel_io0));
+ clks[ssp1_sel] = mxs_clk_mux("ssp1_sel", CLKSEQ, 4, 1, sel_io0, ARRAY_SIZE(sel_io0));
+ clks[ssp2_sel] = mxs_clk_mux("ssp2_sel", CLKSEQ, 5, 1, sel_io1, ARRAY_SIZE(sel_io1));
+ clks[ssp3_sel] = mxs_clk_mux("ssp3_sel", CLKSEQ, 6, 1, sel_io1, ARRAY_SIZE(sel_io1));
+ clks[emi_sel] = mxs_clk_mux("emi_sel", CLKSEQ, 7, 1, emi_sels, ARRAY_SIZE(emi_sels));
+ clks[etm_sel] = mxs_clk_mux("etm_sel", CLKSEQ, 8, 1, sel_cpu, ARRAY_SIZE(sel_cpu));
+ clks[lcdif_sel] = mxs_clk_mux("lcdif_sel", CLKSEQ, 14, 1, sel_pix, ARRAY_SIZE(sel_pix));
+ clks[cpu] = mxs_clk_mux("cpu", CLKSEQ, 18, 1, cpu_sels, ARRAY_SIZE(cpu_sels));
+ clks[ptp_sel] = mxs_clk_mux("ptp_sel", ENET, 19, 1, ptp_sels, ARRAY_SIZE(ptp_sels));
+ clks[cpu_pll] = mxs_clk_div("cpu_pll", "ref_cpu", CPU, 0, 6, 28);
+ clks[cpu_xtal] = mxs_clk_div("cpu_xtal", "ref_xtal", CPU, 16, 10, 29);
+ clks[hbus] = mxs_clk_div("hbus", "cpu", HBUS, 0, 5, 31);
+ clks[xbus] = mxs_clk_div("xbus", "ref_xtal", XBUS, 0, 10, 31);
+ clks[ssp0_div] = mxs_clk_div("ssp0_div", "ssp0_sel", SSP0, 0, 9, 29);
+ clks[ssp1_div] = mxs_clk_div("ssp1_div", "ssp1_sel", SSP1, 0, 9, 29);
+ clks[ssp2_div] = mxs_clk_div("ssp2_div", "ssp2_sel", SSP2, 0, 9, 29);
+ clks[ssp3_div] = mxs_clk_div("ssp3_div", "ssp3_sel", SSP3, 0, 9, 29);
+ clks[gpmi_div] = mxs_clk_div("gpmi_div", "gpmi_sel", GPMI, 0, 10, 29);
+ clks[emi_pll] = mxs_clk_div("emi_pll", "ref_emi", EMI, 0, 6, 28);
+ clks[emi_xtal] = mxs_clk_div("emi_xtal", "ref_xtal", EMI, 8, 4, 29);
+ clks[lcdif_div] = mxs_clk_div("lcdif_div", "lcdif_sel", LCDIF, 0, 13, 29);
+ clks[etm_div] = mxs_clk_div("etm_div", "etm_sel", ETM, 0, 7, 29);
+ clks[clk32k_div] = mxs_clk_fixed_factor("clk32k_div", "ref_xtal", 1, 750);
+ clks[rtc] = mxs_clk_fixed_factor("rtc", "ref_xtal", 1, 768);
+ clks[lradc] = mxs_clk_fixed_factor("lradc", "clk32k", 1, 16);
+ clks[clk32k] = mxs_clk_gate("clk32k", "clk32k_div", XTAL, 26);
+ clks[pwm] = mxs_clk_gate("pwm", "ref_xtal", XTAL, 29);
+ clks[uart] = mxs_clk_gate("uart", "ref_xtal", XTAL, 31);
+ clks[ssp0] = mxs_clk_gate("ssp0", "ssp0_div", SSP0, 31);
+ clks[ssp1] = mxs_clk_gate("ssp1", "ssp1_div", SSP1, 31);
+ clks[ssp2] = mxs_clk_gate("ssp2", "ssp2_div", SSP2, 31);
+ clks[ssp3] = mxs_clk_gate("ssp3", "ssp3_div", SSP3, 31);
+ clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
+ clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
+ clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", LCDIF, 31);
+ clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31);
+ clks[fec] = mxs_clk_gate("fec", "hbus", ENET, 30);
+ clks[usb0_phy] = mxs_clk_gate("usb0_phy", "pll0", PLL0CTRL0, 18);
+ clks[usb1_phy] = mxs_clk_gate("usb1_phy", "pll1", PLL1CTRL0, 18);
+ clks[enet_out] = clk_gate("enet_out", "pll2", ENET, 18);
+ clks[lcdif_comp] = mxs_clk_lcdif("lcdif_comp", clks[ref_pix],
+ clks[lcdif_div], clks[lcdif]);
+
+ clk_set_rate(clks[ref_io0], 480000000);
+ clk_set_rate(clks[ref_io1], 480000000);
+ clk_set_parent(clks[ssp0_sel], clks[ref_io0]);
+ clk_set_parent(clks[ssp1_sel], clks[ref_io0]);
+ clk_set_parent(clks[ssp2_sel], clks[ref_io1]);
+ clk_set_parent(clks[ssp3_sel], clks[ref_io1]);
+ clk_set_rate(clks[ssp0_div], 96000000);
+ clk_set_rate(clks[ssp1_div], 96000000);
+ clk_set_rate(clks[ssp2_div], 96000000);
+ clk_set_rate(clks[ssp3_div], 96000000);
+ clk_set_parent(clks[lcdif_sel], clks[ref_pix]);
+ clk_enable(clks[enet_out]);
+
+ clkdev_add_physbase(clks[ssp0], IMX_SSP0_BASE, NULL);
+ clkdev_add_physbase(clks[ssp1], IMX_SSP1_BASE, NULL);
+ clkdev_add_physbase(clks[ssp2], IMX_SSP2_BASE, NULL);
+ clkdev_add_physbase(clks[ssp3], IMX_SSP3_BASE, NULL);
+ clkdev_add_physbase(clks[fec], IMX_FEC0_BASE, NULL);
+ clkdev_add_physbase(clks[xbus], IMX_DBGUART_BASE, NULL);
+ clkdev_add_physbase(clks[hbus], IMX_OCOTP_BASE, NULL);
+ clkdev_add_physbase(clks[uart], IMX_UART0_BASE, NULL);
+ clkdev_add_physbase(clks[uart], IMX_UART1_BASE, NULL);
+ clkdev_add_physbase(clks[uart], IMX_UART2_BASE, NULL);
+ clkdev_add_physbase(clks[uart], IMX_UART3_BASE, NULL);
+ clkdev_add_physbase(clks[uart], IMX_UART4_BASE, NULL);
+ clkdev_add_physbase(clks[gpmi], MXS_GPMI_BASE, NULL);
+ if (IS_ENABLED(CONFIG_DRIVER_VIDEO_STM))
+ clkdev_add_physbase(clks[lcdif_comp], IMX_FB_BASE, NULL);
+
+ return 0;
+}
+
+static int imx28_ccm_probe(struct device_d *dev)
+{
+ void __iomem *regs;
+
+ regs = dev_request_mem_region(dev, 0);
+
+ mx28_clocks_init(regs);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx28_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx28-clkctrl",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx28_ccm_driver = {
+ .probe = imx28_ccm_probe,
+ .name = "imx28-clkctrl",
+ .of_compatible = DRV_OF_COMPAT(imx28_ccm_dt_ids),
+};
+
+static int imx28_ccm_init(void)
+{
+ return platform_driver_register(&imx28_ccm_driver);
+}
+postcore_initcall(imx28_ccm_init);
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 06/17] ARM: MXS: remove board specific clock setups
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (4 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 05/17] ARM: MXS: add clk drivers Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 07/17] mci: mxs: Use dev_* Sascha Hauer
` (10 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
Some boards have board specific special clock setups. These are now
done in the SoC specific clock drivers.
It is assumed that most board specific clock setup is done based on
copy/paste from U-Boot. The generalized clock setup differs from
some boards:
- ioclk are adjusted to 480MHz
- ssp clocks are adjusted to 96MHz
- enet out clock is enabled
Some boards adjusted the ioclk to 320MHz and the ssp clock to 160MHz.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/boards/chumby_falconwing/falconwing.c | 3 ---
arch/arm/boards/crystalfontz-cfa10036/cfa10036.c | 5 -----
arch/arm/boards/freescale-mx23-evk/mx23-evk.c | 3 ---
arch/arm/boards/freescale-mx28-evk/mx28-evk.c | 8 --------
arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c | 6 ------
arch/arm/boards/karo-tx28/tx28-stk5.c | 5 -----
6 files changed, 30 deletions(-)
diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
index 720fe32..ab73be6 100644
--- a/arch/arm/boards/chumby_falconwing/falconwing.c
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -290,9 +290,6 @@ static int falconwing_devices_init(void)
for (i = 0; i < ARRAY_SIZE(pad_setup); i++)
imx_gpio_mode(pad_setup[i]);
- imx_set_ioclk(480000000); /* enable IOCLK to run at the PLL frequency */
- /* run the SSP unit clock at 100,000 kHz */
- imx_set_sspclk(0, 100000000, 1);
add_generic_device("mxs_mci", 0, NULL, IMX_SSP1_BASE, 0x2000,
IORESOURCE_MEM, &mci_pdata);
add_generic_device("stmfb", 0, NULL, IMX_FB_BASE, 4096,
diff --git a/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c b/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c
index a37b089..56a695f 100644
--- a/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c
+++ b/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c
@@ -122,11 +122,6 @@ static int cfa10036_devices_init(void)
for (i = 0; i < ARRAY_SIZE(cfa10036_pads); i++)
imx_gpio_mode(cfa10036_pads[i]);
- /* enable IOCLK0 to run at the PLL frequency */
- imx_set_ioclk(0, 480000000);
- /* run the SSP unit clock at 100 MHz */
- imx_set_sspclk(0, 100000000, 1);
-
armlinux_set_bootparams((void *)IMX_MEMORY_BASE + 0x100);
armlinux_set_architecture(MACH_TYPE_CFA10036);
diff --git a/arch/arm/boards/freescale-mx23-evk/mx23-evk.c b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
index 76377b1..9f63814 100644
--- a/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
+++ b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
@@ -109,9 +109,6 @@ static int mx23_evk_devices_init(void)
armlinux_set_bootparams((void*)IMX_MEMORY_BASE + 0x100);
armlinux_set_architecture(MACH_TYPE_MX23EVK);
- imx_set_ioclk(480000000); /* enable IOCLK to run at the PLL frequency */
- imx_set_sspclk(0, 100000000, 1);
-
add_generic_device("mxs_mci", DEVICE_ID_DYNAMIC, NULL, IMX_SSP1_BASE,
0x8000, IORESOURCE_MEM, &mci_pdata);
diff --git a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
index 364b6ee..bc28463 100644
--- a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
+++ b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
@@ -253,14 +253,6 @@ static int mx28_evk_devices_init(void)
for (i = 0; i < ARRAY_SIZE(mx28evk_pads); i++)
imx_gpio_mode(mx28evk_pads[i]);
- /* enable IOCLK0 to run at the PLL frequency */
- imx_set_ioclk(0, 480000000);
- imx_set_ioclk(1, 320000000);
- /* run the SSP unit clock at 100 MHz */
- imx_set_sspclk(0, 100000000, 1);
- /* run the SSP unit 2 clock at 160Mhz */
- imx_set_sspclk(2, 160000000, 1);
-
armlinux_set_bootparams((void *)IMX_MEMORY_BASE + 0x100);
armlinux_set_architecture(MACH_TYPE_MX28EVK);
diff --git a/arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c b/arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c
index 9620e85..ca6c5da 100644
--- a/arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c
+++ b/arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c
@@ -124,12 +124,6 @@ static int imx23_olinuxino_devices_init(void)
armlinux_set_bootparams((void *)IMX_MEMORY_BASE + 0x100);
armlinux_set_architecture(MACH_TYPE_IMX233_OLINUXINO);
- /* enable IOCLK to run at the PLL frequency */
- imx_set_ioclk(480000000);
-
- /* run the SSP unit clock at 100,000 kHz */
- imx_set_sspclk(0, 100000000, 1);
-
add_generic_device("mxs_mci", DEVICE_ID_DYNAMIC, NULL, IMX_SSP1_BASE,
0x8000, IORESOURCE_MEM, &mci_pdata);
diff --git a/arch/arm/boards/karo-tx28/tx28-stk5.c b/arch/arm/boards/karo-tx28/tx28-stk5.c
index a0109d6..ae633b8 100644
--- a/arch/arm/boards/karo-tx28/tx28-stk5.c
+++ b/arch/arm/boards/karo-tx28/tx28-stk5.c
@@ -371,11 +371,6 @@ void base_board_init(void)
for (i = 0; i < ARRAY_SIZE(tx28_starterkit_pad_setup); i++)
imx_gpio_mode(tx28_starterkit_pad_setup[i]);
- /* enable IOCLK0 to run at the PLL frequency */
- imx_set_ioclk(0, 480000000);
- /* run the SSP unit clock at 100 MHz */
- imx_set_sspclk(0, 100000000, 1);
-
add_generic_device("mxs_mci", 0, NULL, IMX_SSP0_BASE, 0x2000,
IORESOURCE_MEM, &mci_pdata);
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 07/17] mci: mxs: Use dev_*
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (5 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 06/17] ARM: MXS: remove board specific clock setups Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 08/17] net: fec: Use clk API unconditionally Sascha Hauer
` (9 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/mxs.c | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/drivers/mci/mxs.c b/drivers/mci/mxs.c
index e6f40eb..cb2911a 100644
--- a/drivers/mci/mxs.c
+++ b/drivers/mci/mxs.c
@@ -116,22 +116,22 @@ static void mxs_mci_finish_request(struct mxs_mci_host *mxs_mci)
* @param status HW_SSP_STATUS's content
* @return 0 if no error, negative values else
*/
-static int mxs_mci_get_cmd_error(unsigned status)
+static int mxs_mci_get_cmd_error(struct mxs_mci_host *mxs_mci, unsigned status)
{
if (status & SSP_STATUS_ERROR)
- pr_debug("Status Reg reports %08X\n", status);
+ dev_dbg(mxs_mci->host.hw_dev, "Status Reg reports %08X\n", status);
if (status & SSP_STATUS_TIMEOUT) {
- pr_debug("CMD timeout\n");
+ dev_dbg(mxs_mci->host.hw_dev, "CMD timeout\n");
return -ETIMEDOUT;
} else if (status & SSP_STATUS_RESP_TIMEOUT) {
- pr_debug("RESP timeout\n");
+ dev_dbg(mxs_mci->host.hw_dev, "RESP timeout\n");
return -ETIMEDOUT;
} else if (status & SSP_STATUS_RESP_CRC_ERR) {
- pr_debug("CMD crc error\n");
+ dev_dbg(mxs_mci->host.hw_dev, "CMD crc error\n");
return -EILSEQ;
} else if (status & SSP_STATUS_RESP_ERR) {
- pr_debug("RESP error\n");
+ dev_dbg(mxs_mci->host.hw_dev, "RESP error\n");
return -EIO;
}
@@ -168,7 +168,8 @@ static int mxs_mci_read_data(struct mxs_mci_host *mxs_mci, void *buffer, unsigne
uint32_t *p = buffer;
if (length & 0x3) {
- pr_debug("Cannot read data sizes not multiple of 4 (request for %u detected)\n",
+ dev_dbg(mxs_mci->host.hw_dev,
+ "Cannot read data sizes not multiple of 4 (request for %u detected)\n",
length);
return -EINVAL;
}
@@ -206,7 +207,8 @@ static int mxs_mci_write_data(struct mxs_mci_host *mxs_mci, const void *buffer,
const uint32_t *p = buffer;
if (length & 0x3) {
- pr_debug("Cannot write data sizes not multiple of 4 (request for %u detected)\n",
+ dev_dbg(mxs_mci->host.hw_dev,
+ "Cannot write data sizes not multiple of 4 (request for %u detected)\n",
length);
return -EINVAL;
}
@@ -320,7 +322,7 @@ static int mxs_mci_std_cmds(struct mxs_mci_host *mxs_mci, struct mci_cmd *cmd)
if (cmd->resp_type & MMC_RSP_PRESENT)
mxs_mci_get_cards_response(mxs_mci, cmd);
- return mxs_mci_get_cmd_error(readl(mxs_mci->regs + HW_SSP_STATUS));
+ return mxs_mci_get_cmd_error(mxs_mci, readl(mxs_mci->regs + HW_SSP_STATUS));
}
/**
@@ -385,7 +387,7 @@ static int mxs_mci_adtc(struct mxs_mci_host *mxs_mci, struct mci_cmd *cmd,
err = mxs_mci_transfer_data(mxs_mci, data);
if (err != 0) {
- pr_debug(" Transfering data failed\n");
+ dev_dbg(mxs_mci->host.hw_dev, "Transfering data failed with %d\n", err);
return err;
}
@@ -436,7 +438,7 @@ static unsigned mxs_mci_setup_clock_speed(struct mxs_mci_host *mxs_mci, unsigned
break;
}
if (div >= 255) {
- pr_warning("Cannot set clock to %d Hz\n", nc);
+ dev_warn(mxs_mci->host.hw_dev, "Cannot set clock to %d Hz\n", nc);
return 0;
}
@@ -531,7 +533,8 @@ static void mxs_mci_set_ios(struct mci_host *host, struct mci_ios *ios)
}
mxs_mci->clock = mxs_mci_setup_clock_speed(mxs_mci, ios->clock);
- pr_debug("IO settings: frequency=%u Hz\n", mxs_mci->clock);
+
+ dev_dbg(host->hw_dev, "IO settings: frequency=%u Hz\n", mxs_mci->clock);
}
/* ----------------------------------------------------------------------- */
@@ -557,7 +560,7 @@ static int mxs_mci_probe(struct device_d *hw_dev)
struct mci_host *host;
if (hw_dev->platform_data == NULL) {
- pr_err("Missing platform data\n");
+ dev_err(hw_dev, "Missing platform data\n");
return -EINVAL;
}
@@ -600,18 +603,18 @@ static int mxs_mci_probe(struct device_d *hw_dev)
#endif
if (pd->f_min == 0) {
host->f_min = mxs_mci_get_unit_clock(mxs_mci) / 254 / 256;
- pr_debug("Min. frequency is %u Hz\n", host->f_min);
+ dev_dbg(hw_dev, "Min. frequency is %u Hz\n", host->f_min);
} else {
host->f_min = pd->f_min;
- pr_debug("Min. frequency is %u Hz, could be %u Hz\n",
+ dev_dbg(hw_dev, "Min. frequency is %u Hz, could be %u Hz\n",
host->f_min, mxs_mci_get_unit_clock(mxs_mci) / 254 / 256);
}
if (pd->f_max == 0) {
host->f_max = mxs_mci_get_unit_clock(mxs_mci) / 2 / 1;
- pr_debug("Max. frequency is %u Hz\n", host->f_max);
+ dev_dbg(hw_dev, "Max. frequency is %u Hz\n", host->f_max);
} else {
host->f_max = pd->f_max;
- pr_debug("Max. frequency is %u Hz, could be %u Hz\n",
+ dev_dbg(hw_dev, "Max. frequency is %u Hz, could be %u Hz\n",
host->f_max, mxs_mci_get_unit_clock(mxs_mci) / 2 / 1);
}
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 08/17] net: fec: Use clk API unconditionally
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (6 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 07/17] mci: mxs: Use dev_* Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 09/17] mci: mxs: use common clk API Sascha Hauer
` (8 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec_imx.c | 31 +++++++++----------------------
1 file changed, 9 insertions(+), 22 deletions(-)
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 1346c91..2f31352 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -45,19 +45,6 @@ struct fec_frame {
uint8_t head[16]; /* MAC header(6 + 6 + 2) + 2(aligned) */
};
-#ifdef CONFIG_COMMON_CLK
-static inline unsigned long fec_clk_get_rate(struct fec_priv *fec)
-{
- return clk_get_rate(fec->clk);
-}
-#else
-static inline unsigned long fec_clk_get_rate(struct fec_priv *fec)
-{
- return imx_get_fecclk();
-}
-#endif
-
-
/*
* MII-interface related functions
*/
@@ -69,7 +56,7 @@ static int fec_miibus_read(struct mii_bus *bus, int phyAddr, int regAddr)
uint32_t phy; /* convenient holder for the PHY */
uint64_t start;
- writel(((fec_clk_get_rate(fec) >> 20) / 5) << 1,
+ writel(((clk_get_rate(fec->clk) >> 20) / 5) << 1,
fec->regs + FEC_MII_SPEED);
/*
* reading from any PHY's register is done by properly
@@ -112,7 +99,7 @@ static int fec_miibus_write(struct mii_bus *bus, int phyAddr,
uint32_t phy; /* convenient holder for the PHY */
uint64_t start;
- writel(((fec_clk_get_rate(fec) >> 20) / 5) << 1,
+ writel(((clk_get_rate(fec->clk) >> 20) / 5) << 1,
fec->regs + FEC_MII_SPEED);
reg = regAddr << FEC_MII_DATA_RA_SHIFT;
@@ -305,7 +292,7 @@ static int fec_init(struct eth_device *dev)
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
* and do not drop the Preamble.
*/
- writel(((fec_clk_get_rate(fec) >> 20) / 5) << 1,
+ writel(((clk_get_rate(fec->clk) >> 20) / 5) << 1,
fec->regs + FEC_MII_SPEED);
if (fec->interface == PHY_INTERFACE_MODE_RMII) {
@@ -674,14 +661,14 @@ static int fec_probe(struct device_d *dev)
edev->set_ethaddr = fec_set_hwaddr;
edev->parent = dev;
- if (IS_ENABLED(CONFIG_COMMON_CLK)) {
- fec->clk = clk_get(dev, NULL);
- if (IS_ERR(fec->clk)) {
- ret = PTR_ERR(fec->clk);
- goto err_free;
- }
+ fec->clk = clk_get(dev, NULL);
+ if (IS_ERR(fec->clk)) {
+ ret = PTR_ERR(fec->clk);
+ goto err_free;
}
+ clk_enable(fec->clk);
+
fec->regs = dev_request_mem_region(dev, 0);
/* Reset chip. */
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 09/17] mci: mxs: use common clk API
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (7 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 08/17] net: fec: Use clk API unconditionally Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 10/17] mtd: gpmi-nand: switch to clk support Sascha Hauer
` (7 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/mxs.c | 60 ++++++++++++++++++-------------------------------------
1 file changed, 19 insertions(+), 41 deletions(-)
diff --git a/drivers/mci/mxs.c b/drivers/mci/mxs.c
index cb2911a..023f922 100644
--- a/drivers/mci/mxs.c
+++ b/drivers/mci/mxs.c
@@ -36,6 +36,8 @@
#include <errno.h>
#include <clock.h>
#include <io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <asm/bitops.h>
#include <mach/mxs.h>
#include <mach/imx-regs.h>
@@ -49,8 +51,8 @@
struct mxs_mci_host {
struct mci_host host;
void __iomem *regs;
+ struct clk *clk;
unsigned clock; /* current clock speed in Hz ("0" if disabled) */
- unsigned index;
#ifdef CONFIG_MCI_INFO
unsigned f_min;
unsigned f_max;
@@ -61,16 +63,6 @@ struct mxs_mci_host {
#define to_mxs_mci(mxs) container_of(mxs, struct mxs_mci_host, host)
/**
- * Get the SSP clock rate
- * @param hw_dev Host interface device instance
- * @return Unit's clock in [Hz]
- */
-static unsigned mxs_mci_get_unit_clock(struct mxs_mci_host *mxs_mci)
-{
- return imx_get_sspclk(mxs_mci->index);
-}
-
-/**
* Get MCI cards response if defined for the type of command
* @param hw_dev Host interface device instance
* @param cmd Command description
@@ -430,7 +422,7 @@ static unsigned mxs_mci_setup_clock_speed(struct mxs_mci_host *mxs_mci, unsigned
return 0;
}
- ssp = mxs_mci_get_unit_clock(mxs_mci);
+ ssp = clk_get_rate(mxs_mci->clk);
for (div = 2; div < 255; div += 2) {
rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ssp, nc), div);
@@ -558,6 +550,7 @@ static int mxs_mci_probe(struct device_d *hw_dev)
struct mxs_mci_platform_data *pd = hw_dev->platform_data;
struct mxs_mci_host *mxs_mci;
struct mci_host *host;
+ unsigned long rate;
if (hw_dev->platform_data == NULL) {
dev_err(hw_dev, "Missing platform data\n");
@@ -578,44 +571,29 @@ static int mxs_mci_probe(struct device_d *hw_dev)
host->voltages = pd->voltages;
host->host_caps = pd->caps;
-#ifdef CONFIG_ARCH_IMX23
- mxs_mci->index = 0; /* there is only one clock for all */
-#endif
-#ifdef CONFIG_ARCH_IMX28
- /* one dedicated clock per unit */
- switch (hw_dev->resource[0].start) {
- case IMX_SSP0_BASE:
- mxs_mci->index = 0;
- break;
- case IMX_SSP1_BASE:
- mxs_mci->index = 1;
- break;
- case IMX_SSP2_BASE:
- mxs_mci->index = 2;
- break;
- case IMX_SSP3_BASE:
- mxs_mci->index = 3;
- break;
- default:
- pr_debug("Unknown SSP unit at address 0x%p\n", mxs_mci->regs);
- return 0;
- }
-#endif
+ mxs_mci->clk = clk_get(hw_dev, NULL);
+ if (IS_ERR(mxs_mci->clk))
+ return PTR_ERR(mxs_mci->clk);
+
+ clk_enable(mxs_mci->clk);
+
+ rate = clk_get_rate(mxs_mci->clk);
+
if (pd->f_min == 0) {
- host->f_min = mxs_mci_get_unit_clock(mxs_mci) / 254 / 256;
+ host->f_min = rate / 254 / 256;
dev_dbg(hw_dev, "Min. frequency is %u Hz\n", host->f_min);
} else {
host->f_min = pd->f_min;
- dev_dbg(hw_dev, "Min. frequency is %u Hz, could be %u Hz\n",
- host->f_min, mxs_mci_get_unit_clock(mxs_mci) / 254 / 256);
+ dev_dbg(hw_dev, "Min. frequency is %u Hz, could be %lu Hz\n",
+ host->f_min, rate / 254 / 256);
}
if (pd->f_max == 0) {
- host->f_max = mxs_mci_get_unit_clock(mxs_mci) / 2 / 1;
+ host->f_max = rate / 2 / 1;
dev_dbg(hw_dev, "Max. frequency is %u Hz\n", host->f_max);
} else {
host->f_max = pd->f_max;
- dev_dbg(hw_dev, "Max. frequency is %u Hz, could be %u Hz\n",
- host->f_max, mxs_mci_get_unit_clock(mxs_mci) / 2 / 1);
+ dev_dbg(hw_dev, "Max. frequency is %u Hz, could be %lu Hz\n",
+ host->f_max, rate / 2 / 1);
}
if (IS_ENABLED(CONFIG_MCI_INFO)) {
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 10/17] mtd: gpmi-nand: switch to clk support
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (8 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 09/17] mci: mxs: use common clk API Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 11/17] serial: auart: Use " Sascha Hauer
` (6 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/nand_mxs.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index dd43a95..56d5ecf 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -21,6 +21,8 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <common.h>
#include <malloc.h>
#include <errno.h>
@@ -140,6 +142,7 @@
struct mxs_nand_info {
struct nand_chip nand_chip;
void __iomem *io_base;
+ struct clk *clk;
struct mtd_info mtd;
u32 version;
@@ -1147,8 +1150,6 @@ int mxs_nand_hw_init(struct mxs_nand_info *info)
/* Init the DMA controller. */
mxs_dma_init();
- imx_enable_nandclk();
-
/* Reset the GPMI block. */
ret = mxs_reset_block(gpmi_regs + GPMI_CTRL0, 0);
if (ret)
@@ -1200,6 +1201,12 @@ static int mxs_nand_probe(struct device_d *dev)
/* XXX: Remove u-boot specific access pointers and use io_base instead? */
nand_info->io_base = dev_request_mem_region(dev, 0);
+ nand_info->clk = clk_get(dev, NULL);
+ if (IS_ERR(nand_info->clk))
+ return PTR_ERR(nand_info->clk);
+
+ clk_enable(nand_info->clk);
+
err = mxs_nand_alloc_buffers(nand_info);
if (err)
goto err1;
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 11/17] serial: auart: Use clk support
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (9 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 10/17] mtd: gpmi-nand: switch to clk support Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 12/17] serial: stm: " Sascha Hauer
` (5 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/serial/serial_auart.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/serial/serial_auart.c b/drivers/serial/serial_auart.c
index a69e65b..98f7c75 100644
--- a/drivers/serial/serial_auart.c
+++ b/drivers/serial/serial_auart.c
@@ -42,6 +42,8 @@
#include <io.h>
#include <malloc.h>
#include <notifier.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/clock.h>
#include <mach/mxs.h>
@@ -92,6 +94,7 @@ struct auart_priv {
int baudrate;
struct notifier_block notify;
void __iomem *base;
+ struct clk *clk;
};
static void auart_serial_putc(struct console_device *cdev, char c)
@@ -143,7 +146,7 @@ static int auart_serial_setbaudrate(struct console_device *cdev, int new_baudrat
writel(0x0, priv->base + HW_UARTAPP_CTRL2);
/* Calculate and set baudrate */
- quot = (imx_get_xclk() * 32) / new_baudrate;
+ quot = (clk_get_rate(priv->clk) * 32) / new_baudrate;
reg = BF_UARTAPP_LINECTRL_BAUD_DIVFRAC(quot & 0x3F) |
BF_UARTAPP_LINECTRL_BAUD_DIVINT(quot >> 6) |
BF_UARTAPP_LINECTRL_WLEN(3) |
@@ -194,6 +197,9 @@ static int auart_serial_probe(struct device_d *dev)
dev->priv = priv;
priv->base = dev_request_mem_region(dev, 0);
+ priv->clk = clk_get(dev, NULL);
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
auart_serial_init_port(priv);
auart_serial_setbaudrate(cdev, CONFIG_BAUDRATE);
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 12/17] serial: stm: Use clk support
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (10 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 11/17] serial: auart: Use " Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 13/17] spi: mxs: " Sascha Hauer
` (4 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/serial/stm-serial.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c
index a1bb733..0d7484f 100644
--- a/drivers/serial/stm-serial.c
+++ b/drivers/serial/stm-serial.c
@@ -29,6 +29,8 @@
#include <gpio.h>
#include <io.h>
#include <malloc.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
@@ -56,6 +58,7 @@ struct stm_priv {
int baudrate;
struct notifier_block notify;
void __iomem *base;
+ struct clk *clk;
};
static void stm_serial_putc(struct console_device *cdev, char c)
@@ -107,7 +110,7 @@ static int stm_serial_setbaudrate(struct console_device *cdev, int new_baudrate)
writel(0, priv->base + UARTDBGCR);
/* Calculate and set baudrate */
- quot = (imx_get_xclk() * 4) / new_baudrate;
+ quot = (clk_get_rate(priv->clk) * 4) / new_baudrate;
writel(quot & 0x3f, priv->base + UARTDBGFBRD);
writel(quot >> 6, priv->base + UARTDBGIBRD);
@@ -160,6 +163,9 @@ static int stm_serial_probe(struct device_d *dev)
dev->priv = priv;
priv->base = dev_request_mem_region(dev, 0);
+ priv->clk = clk_get(dev, NULL);
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
stm_serial_init_port(priv);
stm_serial_setbaudrate(cdev, CONFIG_BAUDRATE);
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 13/17] spi: mxs: Use clk support
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (11 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 12/17] serial: stm: " Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 14/17] ARM: MXS: octotp: switch to " Sascha Hauer
` (3 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/spi/mxs_spi.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c
index e15f2c2..8dfd6d5 100644
--- a/drivers/spi/mxs_spi.c
+++ b/drivers/spi/mxs_spi.c
@@ -21,6 +21,7 @@
#include <errno.h>
#include <io.h>
#include <linux/clk.h>
+#include <linux/err.h>
#include <asm/mmu.h>
#include <mach/generic.h>
#include <mach/imx-regs.h>
@@ -52,7 +53,7 @@ static inline struct mxs_spi *to_mxs(struct spi_master *master)
static void imx_set_ssp_busclock(struct spi_master *master, uint32_t freq)
{
struct mxs_spi *mxs = to_mxs(master);
- const uint32_t sspclk = imx_get_sspclk(master->bus_num);
+ const uint32_t sspclk = clk_get_rate(mxs->clk);
uint32_t val;
uint32_t divide, rate, tgtclk;
@@ -266,6 +267,9 @@ static int mxs_spi_probe(struct device_d *dev)
mxs->mode = SPI_CPOL | SPI_CPHA;
mxs->regs = dev_request_mem_region(dev, 0);
+ mxs->clk = clk_get(dev, NULL);
+ if (IS_ERR(mxs->clk))
+ return PTR_ERR(mxs->clk);
spi_register_master(master);
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 14/17] ARM: MXS: octotp: switch to clk support
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (12 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 13/17] spi: mxs: " Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 15/17] ARM: MXS: remove imx_enable_enetclk Sascha Hauer
` (2 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-mxs/ocotp.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
index dd98446..6bfa3e2 100644
--- a/arch/arm/mach-mxs/ocotp.c
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -21,11 +21,12 @@
#include <malloc.h>
#include <io.h>
#include <clock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/generic.h>
#include <mach/ocotp.h>
#include <mach/imx-regs.h>
-#include <mach/clock-imx28.h>
#include <mach/power.h>
#define DRIVERNAME "ocotp"
@@ -45,6 +46,7 @@ struct ocotp_priv {
struct cdev cdev;
void __iomem *base;
unsigned int write_enable;
+ struct clk *clk;
};
static int mxs_ocotp_wait_busy(struct ocotp_priv *priv)
@@ -131,10 +133,10 @@ static ssize_t mxs_ocotp_cdev_write(struct cdev *cdev, const void *buf, size_t c
work_buf[offset - aligned_offset + i] |= ((u8 *)buf)[i];
/* prepare system for OTP write */
- old_hclk = imx_get_hclk();
+ old_hclk = clk_get_rate(priv->clk);
old_vddio = imx_get_vddio();
- imx_set_hclk(24000000);
+ clk_set_rate(priv->clk, 24000000);
imx_set_vddio(2800000);
writel(OCOTP_CTRL_RD_BANK_OPEN, base + OCOTP_CTRL + BIT_CLR);
@@ -162,7 +164,7 @@ static ssize_t mxs_ocotp_cdev_write(struct cdev *cdev, const void *buf, size_t c
restore_system:
imx_set_vddio(old_vddio);
- imx_set_hclk(old_hclk);
+ clk_set_rate(priv->clk, old_hclk);
free_mem:
free(work_buf);
@@ -180,6 +182,9 @@ static int mxs_ocotp_probe(struct device_d *dev)
struct ocotp_priv *priv = xzalloc(sizeof (*priv));
priv->base = dev_request_mem_region(dev, 0);
+ priv->clk = clk_get(dev, NULL);
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
priv->cdev.dev = dev;
priv->cdev.ops = &mxs_ocotp_ops;
priv->cdev.priv = priv;
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 15/17] ARM: MXS: remove imx_enable_enetclk
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (13 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 14/17] ARM: MXS: octotp: switch to " Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 16/17] video: stm: switch to clk support Sascha Hauer
2013-06-20 6:54 ` [PATCH 17/17] ARM: MXS: remove old clock support Sascha Hauer
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/boards/freescale-mx28-evk/mx28-evk.c | 1 -
arch/arm/boards/karo-tx28/tx28-stk5.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
index bc28463..06f75e5 100644
--- a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
+++ b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
@@ -266,7 +266,6 @@ static int mx28_evk_devices_init(void)
IORESOURCE_MEM, NULL);
mx28_evk_get_ethaddr(); /* must be after registering ocotp */
- imx_enable_enetclk();
mx28_evk_fec_reset();
add_generic_device("imx28-fec", 0, NULL, IMX_FEC0_BASE, 0x4000,
IORESOURCE_MEM, &fec_info);
diff --git a/arch/arm/boards/karo-tx28/tx28-stk5.c b/arch/arm/boards/karo-tx28/tx28-stk5.c
index ae633b8..b969e4b 100644
--- a/arch/arm/boards/karo-tx28/tx28-stk5.c
+++ b/arch/arm/boards/karo-tx28/tx28-stk5.c
@@ -387,7 +387,6 @@ void base_board_init(void)
tx28_get_ethaddr();
- imx_enable_enetclk();
add_generic_device("imx28-fec", 0, NULL, IMX_FEC0_BASE, 0x4000,
IORESOURCE_MEM, &fec_info);
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 16/17] video: stm: switch to clk support
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (14 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 15/17] ARM: MXS: remove imx_enable_enetclk Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
2013-06-20 6:54 ` [PATCH 17/17] ARM: MXS: remove old clock support Sascha Hauer
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/video/stm.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/video/stm.c b/drivers/video/stm.c
index 606e39a..d5212f8 100644
--- a/drivers/video/stm.c
+++ b/drivers/video/stm.c
@@ -24,8 +24,9 @@
#include <errno.h>
#include <xfuncs.h>
#include <io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/imx-regs.h>
-#include <mach/clock.h>
#include <mach/fb.h>
#define HW_LCDIF_CTRL 0x00
@@ -144,6 +145,7 @@ struct imxfb_info {
struct fb_info info;
struct device_d *hw_dev;
struct imx_fb_platformdata *pdata;
+ struct clk *clk;
};
/* the RGB565 true colour mode */
@@ -327,7 +329,7 @@ static int stmfb_activate_var(struct fb_info *fb_info)
/** @todo ensure HCLK is active at this point of time! */
- size = imx_set_lcdifclk(PICOS2KHZ(mode->pixclock) * 1000);
+ size = clk_set_rate(fbi->clk, PICOS2KHZ(mode->pixclock) * 1000);
if (size == 0) {
dev_dbg(fbi->hw_dev, "Unable to set a valid pixel clock\n");
return -EINVAL;
@@ -490,6 +492,9 @@ static int stmfb_probe(struct device_d *hw_dev)
fbi.hw_dev = hw_dev;
fbi.base = dev_request_mem_region(hw_dev, 0);
fbi.pdata = pdata;
+ fbi.clk = clk_get(hw_dev, NULL);
+ if (IS_ERR(fbi.clk))
+ return PTR_ERR(fbi.clk);
/* add runtime video info */
fbi.info.mode_list = pdata->mode_list;
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 17/17] ARM: MXS: remove old clock support
2013-06-20 6:54 [PATCH] convert MXS to common clk Sascha Hauer
` (15 preceding siblings ...)
2013-06-20 6:54 ` [PATCH 16/17] video: stm: switch to clk support Sascha Hauer
@ 2013-06-20 6:54 ` Sascha Hauer
16 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2013-06-20 6:54 UTC (permalink / raw)
To: barebox; +Cc: Juergen Beisert
The old MXS clock support is now unused and can be removed.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-mxs/Makefile | 5 +-
arch/arm/mach-mxs/imx.c | 16 -
arch/arm/mach-mxs/imx_lcd_clk.c | 150 ----------
arch/arm/mach-mxs/include/mach/clock-imx23.h | 30 --
arch/arm/mach-mxs/include/mach/clock-imx28.h | 33 --
arch/arm/mach-mxs/include/mach/clock.h | 7 -
arch/arm/mach-mxs/speed-imx23.c | 315 -------------------
arch/arm/mach-mxs/speed-imx28.c | 432 ---------------------------
8 files changed, 2 insertions(+), 986 deletions(-)
delete mode 100644 arch/arm/mach-mxs/imx_lcd_clk.c
delete mode 100644 arch/arm/mach-mxs/include/mach/clock-imx23.h
delete mode 100644 arch/arm/mach-mxs/include/mach/clock-imx28.h
delete mode 100644 arch/arm/mach-mxs/speed-imx23.c
delete mode 100644 arch/arm/mach-mxs/speed-imx28.c
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index fe93096..a183987 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,6 +1,5 @@
obj-y += imx.o iomux-imx.o power.o common.o
-obj-$(CONFIG_DRIVER_VIDEO_STM) += imx_lcd_clk.o
-obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o clocksource-imx23.o usb-imx23.o soc-imx23.o
-obj-$(CONFIG_ARCH_IMX28) += speed-imx28.o clocksource-imx28.o usb-imx28.o soc-imx28.o
+obj-$(CONFIG_ARCH_IMX23) += clocksource-imx23.o usb-imx23.o soc-imx23.o
+obj-$(CONFIG_ARCH_IMX28) += clocksource-imx28.o usb-imx28.o soc-imx28.o
obj-$(CONFIG_MXS_OCOTP) += ocotp.o
obj-$(CONFIG_MXS_CMD_BCB) += bcb.o
diff --git a/arch/arm/mach-mxs/imx.c b/arch/arm/mach-mxs/imx.c
index 5acce93..9f195e4 100644
--- a/arch/arm/mach-mxs/imx.c
+++ b/arch/arm/mach-mxs/imx.c
@@ -45,22 +45,6 @@ static int imx_reset_usb_bootstrap(void)
}
device_initcall(imx_reset_usb_bootstrap);
-extern void imx_dump_clocks(void);
-
-static int do_clocks(int argc, char *argv[])
-{
- imx_dump_clocks();
-
- return 0;
-}
-
-BAREBOX_CMD_START(dump_clocks)
- .cmd = do_clocks,
- .usage = "show clock frequencies",
- BAREBOX_CMD_COMPLETE(empty_complete)
-BAREBOX_CMD_END
-
-
static int __silicon_revision = SILICON_REVISION_UNKNOWN;
int silicon_revision_get(void)
diff --git a/arch/arm/mach-mxs/imx_lcd_clk.c b/arch/arm/mach-mxs/imx_lcd_clk.c
deleted file mode 100644
index 455dfcb..0000000
--- a/arch/arm/mach-mxs/imx_lcd_clk.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * (C) Copyright 2010 Juergen Beisert - Pengutronix <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <common.h>
-#include <init.h>
-#include <mach/imx-regs.h>
-#include <mach/clock.h>
-#include <io.h>
-
-#ifdef CONFIG_ARCH_IMX23
-
-# define HW_CLKCTRL_DIS_LCDIF 0x060
-# define CLKCTRL_DIS_LCDIF_GATE (1 << 31)
-# define CLKCTRL_DIS_LCDIF_BUSY (1 << 29)
-# define MASK_DIS_LCDIF_DIV 0xfff
-# define SET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
-# define GET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
-
-# define HW_CLKCTRL_FRAC 0xf0
-# define MASK_PIXFRAC 0x3f
-# define GET_PIXFRAC(x) (((x) >> 16) & MASK_PIXFRAC)
-# define SET_PIXFRAC(x) (((x) & MASK_PIXFRAC) << 16)
-# define CLKCTRL_FRAC_CLKGATEPIX (1 << 23)
-
-# define HW_CLKCTRL_CLKSEQ 0x110
-# define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 1)
-
-#endif
-
-#ifdef CONFIG_ARCH_IMX28
-
-# define HW_CLKCTRL_DIS_LCDIF 0x120
-# define CLKCTRL_DIS_LCDIF_GATE (1 << 31)
-# define CLKCTRL_DIS_LCDIF_BUSY (1 << 29)
-# define MASK_DIS_LCDIF_DIV 0x1fff
-# define SET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
-# define GET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
-
-/* note: On i.MX28 this is called 'FRAC1' */
-# define HW_CLKCTRL_FRAC 0x1c0
-# define MASK_PIXFRAC 0x3f
-# define GET_PIXFRAC(x) ((x) & MASK_PIXFRAC)
-# define SET_PIXFRAC(x) ((x) & MASK_PIXFRAC)
-# define CLKCTRL_FRAC_CLKGATEPIX (1 << 7)
-
-# define HW_CLKCTRL_CLKSEQ 0x1d0
-# define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 14)
-
-#endif
-
-unsigned imx_get_lcdifclk(void)
-{
- unsigned rate = (imx_get_mpllclk() / 1000) * 18U;
- unsigned div;
-
- div = GET_PIXFRAC(readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC));
- if (div != 0U) {
- rate /= div;
- div = GET_DIS_LCDIF_DIV(readl(IMX_CCM_BASE +
- HW_CLKCTRL_DIS_LCDIF));
- if (div != 0U)
- rate /= div;
- else
- pr_debug("LCDIF clock has divisor 0!\n");
- } else
- pr_debug("LCDIF clock has frac divisor 0!\n");
-
- return rate * 1000;
-}
-
-/*
- * The source of the pixel clock can be the external 24 MHz crystal or the
- * internal PLL running at 480 MHz. In order to support at least VGA sized
- * displays/resolutions this routine forces the PLL as the clock source.
- */
-unsigned imx_set_lcdifclk(unsigned nc)
-{
- unsigned frac, best_frac = 0, div, best_div = 0, result;
- int delta, best_delta = 0xffffff;
- unsigned i, parent_rate = imx_get_mpllclk() / 1000;
- uint32_t reg;
-
-#define SH_DIV(NOM, DEN, LSH) ((((NOM) / (DEN)) << (LSH)) + \
- DIV_ROUND_CLOSEST(((NOM) % (DEN)) << (LSH), DEN))
-#define SHIFT 4
-
- nc /= 1000;
- nc <<= SHIFT;
-
- for (frac = 18; frac <= 35; ++frac) {
- for (div = 1; div <= 255; ++div) {
- result = DIV_ROUND_CLOSEST(parent_rate *
- SH_DIV(18U, frac, SHIFT), div);
- delta = nc - result;
- if (abs(delta) < abs(best_delta)) {
- best_delta = delta;
- best_frac = frac;
- best_div = div;
- }
- }
- }
-
- if (best_delta == 0xffffff) {
- pr_debug("Unable to match the pixelclock\n");
- return 0;
- }
-
- pr_debug("Programming PFD=%u,DIV=%u ref_pix=%u MHz PIXCLK=%u kHz\n",
- best_frac, best_div, 480 * 18 / best_frac,
- 480000 * 18 / best_frac / best_div);
-
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
- reg &= ~SET_PIXFRAC(MASK_PIXFRAC);
- reg |= SET_PIXFRAC(best_frac);
- writel(reg, IMX_CCM_BASE + HW_CLKCTRL_FRAC);
- writel(reg & ~CLKCTRL_FRAC_CLKGATEPIX, IMX_CCM_BASE + HW_CLKCTRL_FRAC);
-
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF) & ~MASK_DIS_LCDIF_DIV;
- reg &= ~CLKCTRL_DIS_LCDIF_GATE;
- reg |= SET_DIS_LCDIF_DIV(best_div);
- writel(reg, IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF);
-
- /* Wait for divider update */
- for (i = 0; i < 10000; i++) {
- if (!(readl(IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF) &
- CLKCTRL_DIS_LCDIF_BUSY))
- break;
- }
-
- if (i >= 10000) {
- pr_debug("Setting LCD clock failed\n");
- return 0;
- }
-
- writel(CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF,
- IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_CLR);
-
- return imx_get_lcdifclk();
-}
diff --git a/arch/arm/mach-mxs/include/mach/clock-imx23.h b/arch/arm/mach-mxs/include/mach/clock-imx23.h
deleted file mode 100644
index 6507792..0000000
--- a/arch/arm/mach-mxs/include/mach/clock-imx23.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef MACH_CLOCK_IMX23_H
-# define MACH_CLOCK_IMX23_H
-
-unsigned imx_get_mpllclk(void);
-unsigned imx_get_emiclk(void);
-unsigned imx_get_ioclk(void);
-unsigned imx_get_armclk(void);
-unsigned imx_get_hclk(void);
-unsigned imx_set_hclk(unsigned);
-unsigned imx_get_xclk(void);
-unsigned imx_get_sspclk(unsigned);
-unsigned imx_set_sspclk(unsigned, unsigned, int);
-unsigned imx_set_ioclk(unsigned);
-unsigned imx_set_lcdifclk(unsigned);
-unsigned imx_get_lcdifclk(void);
-void imx_enable_nandclk(void);
-
-#endif /* MACH_CLOCK_IMX23_H */
diff --git a/arch/arm/mach-mxs/include/mach/clock-imx28.h b/arch/arm/mach-mxs/include/mach/clock-imx28.h
deleted file mode 100644
index 0604f0a..0000000
--- a/arch/arm/mach-mxs/include/mach/clock-imx28.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef MACH_CLOCK_IMX28_H
-#define MACH_CLOCK_IMX28_H
-
-unsigned imx_get_mpllclk(void);
-unsigned imx_get_emiclk(void);
-unsigned imx_get_ioclk(unsigned);
-unsigned imx_get_armclk(void);
-unsigned imx_get_hclk(void);
-unsigned imx_set_hclk(unsigned);
-unsigned imx_get_xclk(void);
-unsigned imx_get_sspclk(unsigned);
-unsigned imx_set_sspclk(unsigned, unsigned, int);
-unsigned imx_set_ioclk(unsigned, unsigned);
-unsigned imx_set_lcdifclk(unsigned);
-unsigned imx_get_lcdifclk(void);
-unsigned imx_get_fecclk(void);
-void imx_enable_enetclk(void);
-void imx_enable_nandclk(void);
-
-#endif /* MACH_CLOCK_IMX28_H */
-
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h
index 367297b..adbc330 100644
--- a/arch/arm/mach-mxs/include/mach/clock.h
+++ b/arch/arm/mach-mxs/include/mach/clock.h
@@ -16,11 +16,4 @@
#ifndef __MACH_CLOCK_H
# define __MACH_CLOCK_H
-#if defined CONFIG_ARCH_IMX23
-# include <mach/clock-imx23.h>
-#endif
-#if defined CONFIG_ARCH_IMX28
-# include <mach/clock-imx28.h>
-#endif
-
#endif /* __MACH_CLOCK_H */
diff --git a/arch/arm/mach-mxs/speed-imx23.c b/arch/arm/mach-mxs/speed-imx23.c
deleted file mode 100644
index 14885d5..0000000
--- a/arch/arm/mach-mxs/speed-imx23.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * (C) Copyright 2010 Juergen Beisert - Pengutronix
- *
- * This code is based partially on code of:
- *
- * (c) 2008 Embedded Alley Solutions, Inc.
- * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <common.h>
-#include <init.h>
-#include <io.h>
-#include <mach/imx-regs.h>
-#include <mach/generic.h>
-#include <mach/clock.h>
-
-#define HW_CLKCTRL_PLLCTRL0 0x000
-#define HW_CLKCTRL_PLLCTRL1 0x010
-#define HW_CLKCTRL_CPU 0x20
-# define GET_CPU_XTAL_DIV(x) (((x) >> 16) & 0x3ff)
-# define GET_CPU_PLL_DIV(x) ((x) & 0x3f)
-#define HW_CLKCTRL_HBUS 0x30
-#define HW_CLKCTRL_XBUS 0x40
-#define HW_CLKCTRL_XTAL 0x050
-#define HW_CLKCTRL_PIX 0x060
-/* note: no set/clear register! */
-#define HW_CLKCTRL_SSP 0x070
-/* note: no set/clear register! */
-# define CLKCTRL_SSP_CLKGATE (1 << 31)
-# define CLKCTRL_SSP_BUSY (1 << 29)
-# define CLKCTRL_SSP_DIV_MASK 0x1ff
-# define GET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
-# define SET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
-#define HW_CLKCTRL_GPMI 0x080
-# define CLKCTRL_GPMI_CLKGATE (1 << 31)
-# define CLKCTRL_GPMI_DIV_MASK 0x3ff
-/* note: no set/clear register! */
-#define HW_CLKCTRL_SPDIF 0x090
-/* note: no set/clear register! */
-#define HW_CLKCTRL_EMI 0xa0
-/* note: no set/clear register! */
-# define CLKCTRL_EMI_CLKGATE (1 << 31)
-# define GET_EMI_XTAL_DIV(x) (((x) >> 8) & 0xf)
-# define GET_EMI_PLL_DIV(x) ((x) & 0x3f)
-#define HW_CLKCTRL_SAIF 0x0c0
-#define HW_CLKCTRL_TV 0x0d0
-#define HW_CLKCTRL_ETM 0x0e0
-#define HW_CLKCTRL_FRAC 0xf0
-# define CLKCTRL_FRAC_CLKGATEIO (1 << 31)
-# define GET_IOFRAC(x) (((x) >> 24) & 0x3f)
-# define SET_IOFRAC(x) (((x) & 0x3f) << 24)
-# define CLKCTRL_FRAC_CLKGATEPIX (1 << 23)
-# define GET_PIXFRAC(x) (((x) >> 16) & 0x3f)
-# define CLKCTRL_FRAC_CLKGATEEMI (1 << 15)
-# define GET_EMIFRAC(x) (((x) >> 8) & 0x3f)
-# define CLKCTRL_FRAC_CLKGATECPU (1 << 7)
-# define GET_CPUFRAC(x) ((x) & 0x3f)
-#define HW_CLKCTRL_FRAC1 0x100
-#define HW_CLKCTRL_CLKSEQ 0x110
-# define CLKCTRL_CLKSEQ_BYPASS_ETM (1 << 8)
-# define CLKCTRL_CLKSEQ_BYPASS_CPU (1 << 7)
-# define CLKCTRL_CLKSEQ_BYPASS_EMI (1 << 6)
-# define CLKCTRL_CLKSEQ_BYPASS_SSP (1 << 5)
-# define CLKCTRL_CLKSEQ_BYPASS_GPMI (1 << 4)
-#define HW_CLKCTRL_RESET 0x120
-#define HW_CLKCTRL_STATUS 0x130
-#define HW_CLKCTRL_VERSION 0x140
-
-unsigned imx_get_mpllclk(void)
-{
- /* the main PLL runs at 480 MHz */
- return 480000000;
-}
-
-unsigned imx_get_xtalclk(void)
-{
- /* the external reference runs at 24 MHz */
- return 24000000;
-}
-
-/* used for the SDRAM controller */
-unsigned imx_get_emiclk(void)
-{
- uint32_t reg;
- unsigned rate;
-
- if (readl(IMX_CCM_BASE + HW_CLKCTRL_EMI) & CLKCTRL_EMI_CLKGATE)
- return 0U; /* clock is off */
-
- if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_EMI)
- return imx_get_xtalclk() / GET_EMI_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
-
- rate = imx_get_mpllclk() / 1000;
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
- if (!(reg & CLKCTRL_FRAC_CLKGATEEMI)) {
- rate *= 18U;
- rate /= GET_EMIFRAC(reg);
- }
-
- return (rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI)))
- * 1000;
-}
-
-/*
- * Source of ssp, gpmi, ir
- */
-unsigned imx_get_ioclk(void)
-{
- uint32_t reg;
- unsigned rate = imx_get_mpllclk() / 1000;
-
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
- if (reg & CLKCTRL_FRAC_CLKGATEIO)
- return 0U; /* clock is off */
-
- rate *= 18U;
- rate /= GET_IOFRAC(reg);
- return rate * 1000;
-}
-
-/**
- * Setup a new frequency to the IOCLK domain.
- * @param nc New frequency in [Hz]
- *
- * The FRAC divider for the IOCLK must be between 18 (* 18/18) and 35 (* 18/35)
- */
-unsigned imx_set_ioclk(unsigned nc)
-{
- uint32_t reg;
- unsigned div;
-
- nc /= 1000;
- div = (imx_get_mpllclk() / 1000) * 18;
- div = DIV_ROUND_CLOSEST(div, nc);
- if (div > 0x3f)
- div = 0x3f;
- /* mask the current settings */
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC) & ~(SET_IOFRAC(0x3f));
- writel(reg | SET_IOFRAC(div), IMX_CCM_BASE + HW_CLKCTRL_FRAC);
- /* enable the IO clock at its new frequency */
- writel(CLKCTRL_FRAC_CLKGATEIO, IMX_CCM_BASE + HW_CLKCTRL_FRAC + 8);
-
- return imx_get_ioclk();
-}
-
-/* this is CPU core clock */
-unsigned imx_get_armclk(void)
-{
- uint32_t reg;
- unsigned rate;
-
- if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_CPU)
- return imx_get_xtalclk() / GET_CPU_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
-
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
- if (reg & CLKCTRL_FRAC_CLKGATECPU)
- return 0U; /* should not possible, shouldn't it? */
-
- rate = imx_get_mpllclk() / 1000;
- rate *= 18U;
- rate /= GET_CPUFRAC(reg);
-
- return (rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU)))
- * 1000;
-}
-
-/* this is the AHB and APBH bus clock */
-unsigned imx_get_hclk(void)
-{
- unsigned rate = imx_get_armclk() / 1000;
-
- if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
- rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
- rate = DIV_ROUND_UP(rate, 32);
- } else
- rate = DIV_ROUND_UP(rate,
- readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f);
- return rate * 1000;
-}
-
-unsigned imx_set_hclk(unsigned nc)
-{
- unsigned root_rate = imx_get_armclk();
- unsigned reg, div;
-
- div = DIV_ROUND_UP(root_rate, nc);
- if ((div == 0) || (div >= 32))
- return 0;
-
- if ((root_rate < nc) && (root_rate == 64000000))
- div = 3;
-
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & ~0x3f;
- writel(reg | div, IMX_CCM_BASE + HW_CLKCTRL_HBUS);
-
- while (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & (1 << 31))
- ;
-
- return imx_get_hclk();
-}
-
-/*
- * Source of UART, debug UART, audio, PWM, dri, timer, digctl
- */
-unsigned imx_get_xclk(void)
-{
- unsigned rate = imx_get_xtalclk(); /* runs from the 24 MHz crystal reference */
-
- return rate / (readl(IMX_CCM_BASE + HW_CLKCTRL_XBUS) & 0x3ff);
-}
-
-/* 'index' gets ignored on i.MX23 */
-unsigned imx_get_sspclk(unsigned index)
-{
- unsigned rate;
-
- if (readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & CLKCTRL_SSP_CLKGATE)
- return 0U; /* clock is off */
-
- if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_SSP)
- rate = imx_get_xtalclk();
- else
- rate = imx_get_ioclk();
-
- return rate / GET_SSP_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_SSP));
-}
-
-/**
- * @param index Unit index (ignored on i.MX23)
- * @param nc New frequency in [Hz]
- * @param high != 0 if ioclk should be the source
- * @return The new possible frequency in [kHz]
- */
-unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
-{
- uint32_t reg;
- unsigned ssp_div;
-
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & ~CLKCTRL_SSP_CLKGATE;
- /* Datasheet says: Do not change the DIV setting if the clock is off */
- writel(reg, IMX_CCM_BASE + HW_CLKCTRL_SSP);
- /* Wait while clock is gated */
- while (readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & CLKCTRL_SSP_CLKGATE)
- ;
-
- if (high)
- ssp_div = imx_get_ioclk();
- else
- ssp_div = imx_get_xtalclk();
-
- if (nc > ssp_div) {
- printf("Cannot setup SSP unit clock to %u Hz, base clock is only %u Hz\n", nc, ssp_div);
- ssp_div = 1U;
- } else {
- ssp_div = DIV_ROUND_UP(ssp_div, nc);
- if (ssp_div > CLKCTRL_SSP_DIV_MASK)
- ssp_div = CLKCTRL_SSP_DIV_MASK;
- }
-
- /* Set new divider value */
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & ~CLKCTRL_SSP_DIV_MASK;
- writel(reg | SET_SSP_DIV(ssp_div), IMX_CCM_BASE + HW_CLKCTRL_SSP);
-
- /* Wait until new divider value is set */
- while (readl(IMX_CCM_BASE + HW_CLKCTRL_SSP) & CLKCTRL_SSP_BUSY)
- ;
-
- if (high)
- /* switch to ioclock */
- writel(CLKCTRL_CLKSEQ_BYPASS_SSP, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + 8);
- else
- /* switch to 24 MHz crystal */
- writel(CLKCTRL_CLKSEQ_BYPASS_SSP, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + 4);
-
- return imx_get_sspclk(index);
-}
-
-void imx_enable_nandclk(void)
-{
- uint32_t reg;
-
- /* Clear bypass bit; refman says clear, but fsl-code does set. Hooray! */
- writel(CLKCTRL_CLKSEQ_BYPASS_GPMI,
- IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_SET);
-
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_GPMI) & ~CLKCTRL_GPMI_CLKGATE;
- writel(reg, IMX_CCM_BASE + HW_CLKCTRL_GPMI);
- udelay(1000);
- /* Initialize DIV to 1 */
- reg &= ~CLKCTRL_GPMI_DIV_MASK;
- reg |= 1;
- writel(reg, IMX_CCM_BASE + HW_CLKCTRL_GPMI);
-}
-
-void imx_dump_clocks(void)
-{
- printf("mpll: %10u kHz\n", imx_get_mpllclk() / 1000);
- printf("arm: %10u kHz\n", imx_get_armclk() / 1000);
- printf("ioclk: %10u kHz\n", imx_get_ioclk() / 1000);
- printf("emiclk: %10u kHz\n", imx_get_emiclk() / 1000);
- printf("hclk: %10u kHz\n", imx_get_hclk() / 1000);
- printf("xclk: %10u kHz\n", imx_get_xclk() / 1000);
- printf("ssp: %10u kHz\n", imx_get_sspclk(0) / 1000);
-}
diff --git a/arch/arm/mach-mxs/speed-imx28.c b/arch/arm/mach-mxs/speed-imx28.c
deleted file mode 100644
index 2cab42d..0000000
--- a/arch/arm/mach-mxs/speed-imx28.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * (C) Copyright 2010 Juergen Beisert - Pengutronix <kernel@pengutronix.de>
- *
- * This code is based partially on code that has:
- *
- * (c) 2008 Embedded Alley Solutions, Inc.
- * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#include <common.h>
-#include <init.h>
-#include <io.h>
-#include <mach/imx-regs.h>
-#include <mach/generic.h>
-#include <mach/clock.h>
-
-#define HW_CLKCTRL_PLL0CTRL0 0x000
-#define HW_CLKCTRL_PLL0CTRL1 0x010
-#define HW_CLKCTRL_PLL1CTRL0 0x020
-#define HW_CLKCTRL_PLL1CTRL1 0x030
-#define HW_CLKCTRL_PLL2CTRL0 0x040
-# define CLKCTRL_PLL2CTRL0_CLKGATE (1 << 31)
-# define CLKCTRL_PLL2CTRL0_POWER (1 << 23)
-#define HW_CLKCTRL_CPU 0x50
-# define GET_CPU_XTAL_DIV(x) (((x) >> 16) & 0x3ff)
-# define GET_CPU_PLL_DIV(x) ((x) & 0x3f)
-#define HW_CLKCTRL_HBUS 0x60
-#define HW_CLKCTRL_XBUS 0x70
-#define HW_CLKCTRL_XTAL 0x080
-#define HW_CLKCTRL_SSP0 0x090
-#define HW_CLKCTRL_SSP1 0x0a0
-#define HW_CLKCTRL_SSP2 0x0b0
-#define HW_CLKCTRL_SSP3 0x0c0
-/* note: no set/clear register! */
-# define CLKCTRL_SSP_CLKGATE (1 << 31)
-# define CLKCTRL_SSP_BUSY (1 << 29)
-# define CLKCTRL_SSP_DIV_FRAC_EN (1 << 9)
-# define CLKCTRL_SSP_DIV_MASK 0x1ff
-# define GET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
-# define SET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
-#define HW_CLKCTRL_GPMI 0x0d0
-# define CLKCTRL_GPMI_CLKGATE (1 << 31)
-# define CLKCTRL_GPMI_DIV_MASK 0x3ff
-/* note: no set/clear register! */
-#define HW_CLKCTRL_SPDIF 0x0e0
-/* note: no set/clear register! */
-#define HW_CLKCTRL_EMI 0xf0
-/* note: no set/clear register! */
-# define CLKCTRL_EMI_CLKGATE (1 << 31)
-# define GET_EMI_XTAL_DIV(x) (((x) >> 8) & 0xf)
-# define GET_EMI_PLL_DIV(x) ((x) & 0x3f)
-#define HW_CLKCTRL_SAIF0 0x100
-#define HW_CLKCTRL_SAIF1 0x110
-#define HW_CLKCTRL_DIS_LCDIF 0x120
-# define CLKCTRL_DIS_LCDIF_GATE (1 << 31)
-# define CLKCTRL_DIS_LCDIF_BUSY (1 << 29)
-# define SET_DIS_LCDIF_DIV(x) ((x) & 0x1fff)
-# define GET_DIS_LCDIF_DIV(x) ((x) & 0x1fff)
-#define HW_CLKCTRL_ETM 0x130
-#define HW_CLKCTRL_ENET 0x140
-# define SET_CLKCTRL_ENET_DIV(x) (((x) & 0x3f) << 21)
-# define SET_CLKCTRL_ENET_SEL(x) (((x) & 0x3) << 19)
-# define CLKCTRL_ENET_CLK_OUT_EN (1 << 18)
-#define HW_CLKCTRL_HSADC 0x150
-#define HW_CLKCTRL_FLEXCAN 0x160
-#define HW_CLKCTRL_FRAC0 0x1b0
-# define CLKCTRL_FRAC_CLKGATEIO0 (1 << 31)
-# define GET_IO0FRAC(x) (((x) >> 24) & 0x3f)
-# define SET_IO0FRAC(x) (((x) & 0x3f) << 24)
-# define CLKCTRL_FRAC_CLKGATEIO1 (1 << 23)
-# define GET_IO1FRAC(x) (((x) >> 16) & 0x3f)
-# define SET_IO1FRAC(x) (((x) & 0x3f) << 16)
-# define CLKCTRL_FRAC_CLKGATEEMI (1 << 15)
-# define GET_EMIFRAC(x) (((x) >> 8) & 0x3f)
-# define CLKCTRL_FRAC_CLKGATECPU (1 << 7)
-# define GET_CPUFRAC(x) ((x) & 0x3f)
-#define HW_CLKCTRL_FRAC1 0x1c0
-# define CLKCTRL_FRAC_CLKGATEGPMI (1 << 23)
-# define GET_GPMIFRAC(x) (((x) >> 16) & 0x3f)
-# define CLKCTRL_FRAC_CLKGATEHSADC (1 << 15)
-# define GET_HSADCFRAC(x) (((x) >> 8) & 0x3f)
-# define CLKCTRL_FRAC_CLKGATEPIX (1 << 7)
-# define GET_PIXFRAC(x) ((x) & 0x3f)
-# define SET_PIXFRAC(x) ((x) & 0x3f)
-#define HW_CLKCTRL_CLKSEQ 0x1d0
-# define CLKCTRL_CLKSEQ_BYPASS_CPU (1 << 18)
-# define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 14)
-# define CLKCTRL_CLKSEQ_BYPASS_ETM (1 << 8)
-# define CLKCTRL_CLKSEQ_BYPASS_EMI (1 << 7)
-# define CLKCTRL_CLKSEQ_BYPASS_SSP3 (1 << 6)
-# define CLKCTRL_CLKSEQ_BYPASS_SSP2 (1 << 5)
-# define CLKCTRL_CLKSEQ_BYPASS_SSP1 (1 << 4)
-# define CLKCTRL_CLKSEQ_BYPASS_SSP0 (1 << 3)
-# define CLKCTRL_CLKSEQ_BYPASS_GPMI (1 << 2)
-# define CLKCTRL_CLKSEQ_BYPASS_SAIF1 (1 << 1)
-# define CLKCTRL_CLKSEQ_BYPASS_SAIF0 (1 << 0)
-#define HW_CLKCTRL_RESET 0x1e0
-#define HW_CLKCTRL_STATUS 0x1f0
-#define HW_CLKCTRL_VERSION 0x200
-
-unsigned imx_get_mpllclk(void)
-{
- /* the main PLL runs at 480 MHz */
- return 480000000;
-}
-
-unsigned imx_get_xtalclk(void)
-{
- /* the external reference runs at 24 MHz */
- return 24000000;
-}
-
-unsigned imx_get_fecclk(void)
-{
- return imx_get_hclk();
-}
-
-
-/* used for the SDRAM controller */
-unsigned imx_get_emiclk(void)
-{
- uint32_t reg;
- unsigned rate;
-
- if (readl(IMX_CCM_BASE + HW_CLKCTRL_EMI) & CLKCTRL_EMI_CLKGATE)
- return 0; /* clock is off */
-
- if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_EMI)
- return imx_get_xtalclk() /
- GET_EMI_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
-
- rate = imx_get_mpllclk() / 1000;
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
- if (!(reg & CLKCTRL_FRAC_CLKGATEEMI)) {
- rate *= 18;
- rate /= GET_EMIFRAC(reg);
- }
-
- return (rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI)))
- * 1000;
-}
-
-/*
- * Source of ssp, gpmi, ir
- * @param index 0 or 1 for ioclk0 or ioclock1
- */
-unsigned imx_get_ioclk(unsigned index)
-{
- uint32_t reg;
- unsigned rate = imx_get_mpllclk() / 1000;
-
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
- switch (index) {
- case 0:
- if (reg & CLKCTRL_FRAC_CLKGATEIO0)
- return 0; /* clock is off */
-
- rate *= 18;
- rate /= GET_IO0FRAC(reg);
- break;
- case 1:
- if (reg & CLKCTRL_FRAC_CLKGATEIO1)
- return 0; /* clock is off */
-
- rate *= 18;
- rate /= GET_IO1FRAC(reg);
- break;
- }
-
- return rate * 1000;
-}
-
-/**
- * Setup a new frequency to the IOCLK domain.
- * @param index 0 or 1 for ioclk0 or ioclock1
- * @param nc New frequency in [Hz]
- *
- * The FRAC divider for the IOCLK must be between 18 (* 18/18) and 35 (* 18/35)
- *
- * ioclock0 is the shared clock source of SSP0/SSP1, ioclock1 the shared clock
- * source of SSP2/SSP3
- */
-unsigned imx_set_ioclk(unsigned index, unsigned nc)
-{
- uint32_t reg;
- unsigned div;
-
- nc /= 1000;
- div = (imx_get_mpllclk() / 1000) * 18;
- div = DIV_ROUND_CLOSEST(div, nc);
- if (div > 0x3f)
- div = 0x3f;
-
- switch (index) {
- case 0:
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0) &
- ~(SET_IO0FRAC(0x3f));
- /* mask the current settings */
- writel(reg | SET_IO0FRAC(div), IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
- /* enable the IO clock at its new frequency */
- writel(CLKCTRL_FRAC_CLKGATEIO0,
- IMX_CCM_BASE + HW_CLKCTRL_FRAC0 + BIT_CLR);
- break;
- case 1:
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0) &
- ~(SET_IO1FRAC(0x3f));
- /* mask the current settings */
- writel(reg | SET_IO1FRAC(div), IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
- /* enable the IO clock at its new frequency */
- writel(CLKCTRL_FRAC_CLKGATEIO1,
- IMX_CCM_BASE + HW_CLKCTRL_FRAC0 + BIT_CLR);
- break;
- }
-
- return imx_get_ioclk(index);
-}
-
-/* this is CPU core clock */
-unsigned imx_get_armclk(void)
-{
- uint32_t reg;
- unsigned rate;
-
- if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_CPU)
- return imx_get_xtalclk() /
- GET_CPU_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
-
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
- if (reg & CLKCTRL_FRAC_CLKGATECPU)
- return 0; /* should not possible, shouldn't it? */
-
- rate = (imx_get_mpllclk() / 1000) * 18;
- rate /= GET_CPUFRAC(reg);
-
- return (rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU)))
- * 1000;
-}
-
-/* this is the AHB and APBH bus clock */
-unsigned imx_get_hclk(void)
-{
- unsigned rate = imx_get_armclk() / 1000;
-
- if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
- rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
- rate = DIV_ROUND_UP(rate, 32);
- } else
- rate = DIV_ROUND_UP(rate,
- readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f);
- return rate * 1000;
-}
-
-unsigned imx_set_hclk(unsigned nc)
-{
- unsigned root_rate = imx_get_armclk();
- unsigned reg, div;
-
- div = DIV_ROUND_UP(root_rate, nc);
- if ((div == 0) || (div >= 32))
- return 0;
-
- if ((root_rate < nc) && (root_rate == 64000000))
- div = 3;
-
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & ~0x3f;
- writel(reg | div, IMX_CCM_BASE + HW_CLKCTRL_HBUS);
-
- while (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & (1 << 31))
- ;
-
- return imx_get_hclk();
-}
-
-/*
- * Source of UART, debug UART, audio, PWM, dri, timer, digctl
- */
-unsigned imx_get_xclk(void)
-{
- /* runs from the 24 MHz crystal reference */
- unsigned rate = imx_get_xtalclk();
-
- return rate / (readl(IMX_CCM_BASE + HW_CLKCTRL_XBUS) & 0x3ff);
-}
-
-/**
- * @param index The SSP unit (0...3)
- */
-unsigned imx_get_sspclk(unsigned index)
-{
- unsigned rate, offset, shift, ioclk_index;
-
- if (index > 3) {
- pr_debug("Unknown SSP unit: %u\n", index);
- return 0;
- }
-
- ioclk_index = index >> 1;
-
- offset = HW_CLKCTRL_SSP0 + (0x10 * index);
- shift = CLKCTRL_CLKSEQ_BYPASS_SSP0 << index;
-
- if (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_CLKGATE)
- return 0; /* clock is off */
-
- if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & shift)
- rate = imx_get_xtalclk();
- else
- rate = imx_get_ioclk(ioclk_index);
-
- return rate / GET_SSP_DIV(readl(IMX_CCM_BASE + offset));
-}
-
-/**
- * @param index The SSP unit (0...3)
- * @param nc New frequency in [Hz]
- * @param high != 0 if ioclk should be the source
- * @return The new possible frequency
- */
-unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
-{
- uint32_t reg;
- unsigned ssp_div, offset, shift, ioclk_index;
-
- if (index > 3) {
- pr_debug("Unknown SSP unit: %u\n", index);
- return 0;
- }
-
- ioclk_index = index >> 1;
-
- offset = HW_CLKCTRL_SSP0 + (0x10 * index);
- shift = CLKCTRL_CLKSEQ_BYPASS_SSP0 << index;
-
- reg = readl(IMX_CCM_BASE + offset) & ~CLKCTRL_SSP_CLKGATE;
- /* Datasheet says: Do not change the DIV setting if the clock is off */
- writel(reg, IMX_CCM_BASE + offset);
- /* Wait while clock is gated */
- while (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_CLKGATE)
- ;
-
- if (high)
- ssp_div = imx_get_ioclk(ioclk_index);
- else
- ssp_div = imx_get_xtalclk();
-
- if (nc > ssp_div) {
- printf("Cannot setup SSP unit clock to %u kHz, base clock is "
- "only %u kHz\n", nc, ssp_div);
- ssp_div = 1;
- } else {
- ssp_div = DIV_ROUND_UP(ssp_div, nc);
- if (ssp_div > CLKCTRL_SSP_DIV_MASK)
- ssp_div = CLKCTRL_SSP_DIV_MASK;
- }
-
- /* Set new divider value */
- reg = readl(IMX_CCM_BASE + offset) & ~CLKCTRL_SSP_DIV_MASK;
- writel(reg | SET_SSP_DIV(ssp_div), IMX_CCM_BASE + offset);
-
- /* Wait until new divider value is set */
- while (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_BUSY)
- ;
-
- if (high)
- /* switch to ioclock */
- writel(shift, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_CLR);
- else
- /* switch to 24 MHz crystal */
- writel(shift, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_SET);
-
- return imx_get_sspclk(index);
-}
-
-void imx_enable_enetclk(void)
-{
- uint32_t reg;
-
- /* wake up main enet PLL */
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
- if (!(reg & CLKCTRL_PLL2CTRL0_POWER)) {
- reg |= CLKCTRL_PLL2CTRL0_POWER;
- writel(reg, IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
- udelay(50); /* wait until this PLL locks */
- }
- reg &= ~CLKCTRL_PLL2CTRL0_CLKGATE;
- writel(reg, IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
-
- writel(SET_CLKCTRL_ENET_DIV(1) | SET_CLKCTRL_ENET_SEL(0) |
- CLKCTRL_ENET_CLK_OUT_EN, /* FIXME may be platform specific */
- IMX_CCM_BASE + HW_CLKCTRL_ENET);
-}
-
-void imx_enable_nandclk(void)
-{
- uint32_t reg;
-
- /* Clear bypass bit; refman says clear, but fsl-code does set. Hooray! */
- writel(CLKCTRL_CLKSEQ_BYPASS_GPMI,
- IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_SET);
-
- reg = readl(IMX_CCM_BASE + HW_CLKCTRL_GPMI) & ~CLKCTRL_GPMI_CLKGATE;
- writel(reg, IMX_CCM_BASE + HW_CLKCTRL_GPMI);
- udelay(1000);
- /* Initialize DIV to 1 */
- reg &= ~CLKCTRL_GPMI_DIV_MASK;
- reg |= 1;
- writel(reg, IMX_CCM_BASE + HW_CLKCTRL_GPMI);
-}
-
-void imx_dump_clocks(void)
-{
- printf("mpll: %10u kHz\n", imx_get_mpllclk() / 1000);
- printf("arm: %10u kHz\n", imx_get_armclk() / 1000);
- printf("ioclk0: %10u kHz\n", imx_get_ioclk(0) / 1000);
- printf("ioclk1: %10u kHz\n", imx_get_ioclk(1) / 1000);
- printf("emiclk: %10u kHz\n", imx_get_emiclk() / 1000);
- printf("hclk: %10u kHz\n", imx_get_hclk() / 1000);
- printf("xclk: %10u kHz\n", imx_get_xclk() / 1000);
- printf("ssp0: %10u kHz\n", imx_get_sspclk(0) / 1000);
- printf("ssp1: %10u kHz\n", imx_get_sspclk(1) / 1000);
- printf("ssp2: %10u kHz\n", imx_get_sspclk(2) / 1000);
- printf("ssp3: %10u kHz\n", imx_get_sspclk(3) / 1000);
-}
--
1.8.3.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread