From 89b710e5094fb5721b18c6501a7c813df9f40b14 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 20 Sep 2012 22:03:05 +0200 Subject: clk clkdev: Add clkdev matching based on physbase Most clock/device associations can be done based on the physical base address of the corresponding device. So instead of depending on string matching add an optional possibility to associate a clock lookups with physical addresses. This also has the advantage that the lookups for devicetree based devices can be identical to the platform based devices. Signed-off-by: Sascha Hauer --- drivers/clk/clkdev.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 717fea5689..1ae822ffa6 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -62,6 +62,34 @@ static struct clk *clk_find(const char *dev_id, const char *con_id) return clk; } +static struct clk *clk_find_physbase(struct device_d *dev, const char *con_id) +{ + struct clk_lookup *p; + unsigned long start; + struct clk *clk = ERR_PTR(-ENOSYS); + + if (!dev || !dev->resource) + return ERR_PTR(-ENOSYS); + + start = dev->resource[0].start; + + list_for_each_entry(p, &clocks, node) { + if (p->physbase == ~0) + continue; + if (p->physbase != start) + continue; + if (p->con_id) { + if (!con_id || strcmp(p->con_id, con_id)) + continue; + return p->clk; + } + clk = p->clk; + } + + return clk; + +} + struct clk *clk_get_sys(const char *dev_id, const char *con_id) { struct clk *clk; @@ -77,6 +105,11 @@ EXPORT_SYMBOL(clk_get_sys); struct clk *clk_get(struct device_d *dev, const char *con_id) { const char *dev_id = dev ? dev_name(dev) : NULL; + struct clk *clk; + + clk = clk_find_physbase(dev, con_id); + if (!IS_ERR(clk)) + return clk; return clk_get_sys(dev_id, con_id); } @@ -90,6 +123,9 @@ EXPORT_SYMBOL(clk_put); void clkdev_add(struct clk_lookup *cl) { + if (cl->dev_id) + cl->physbase = ~0; + list_add_tail(&cl->node, &clocks); } EXPORT_SYMBOL(clkdev_add); @@ -97,6 +133,8 @@ EXPORT_SYMBOL(clkdev_add); void __init clkdev_add_table(struct clk_lookup *cl, size_t num) { while (num--) { + if (cl->dev_id) + cl->physbase = ~0; list_add_tail(&cl->node, &clocks); cl++; } @@ -120,6 +158,7 @@ struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, if (!cla) return NULL; + cla->cl.physbase = ~0; cla->cl.clk = clk; if (con_id) { strlcpy(cla->con_id, con_id, sizeof(cla->con_id)); @@ -166,3 +205,19 @@ void clkdev_drop(struct clk_lookup *cl) kfree(cl); } EXPORT_SYMBOL(clkdev_drop); + +int clkdev_add_physbase(struct clk *clk, unsigned long base, const char *id) +{ + struct clk_lookup *cl; + + cl = xzalloc(sizeof(*cl)); + + cl->clk = clk; + cl->con_id = id; + cl->physbase = base; + + clkdev_add(cl); + + return 0; +} +EXPORT_SYMBOL(clkdev_add_physbase); -- cgit v1.2.3 From f2e2e596a221c146082821aa4d9ae249fe9d561a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 20 Sep 2012 22:03:42 +0200 Subject: clk: initial common clk support This adds barebox common clk support loosely based on the Kernel common clk support. differences are: - barebox does not need prepare/unprepare - no parent rate propagation for set_rate - struct clk is not really encapsulated from the drivers Along with the clk support we have support for some basic clk building blocks: - clk-fixed - clk-fixed-factor - clk-mux - clk-divider clk-fixed and clk-fixed-factor are completely generic, clk-mux and clk-divider are currently the way i.MX muxes/dividers are implemented. Signed-off-by: Sascha Hauer --- drivers/clk/Kconfig | 3 + drivers/clk/Makefile | 2 +- drivers/clk/clk-divider.c | 98 ++++++++++++++++++ drivers/clk/clk-fixed-factor.c | 63 ++++++++++++ drivers/clk/clk-fixed.c | 55 ++++++++++ drivers/clk/clk-mux.c | 77 ++++++++++++++ drivers/clk/clk.c | 224 +++++++++++++++++++++++++++++++++++++++++ include/linux/clk.h | 42 ++++++++ 8 files changed, 563 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/clk-divider.c create mode 100644 drivers/clk/clk-fixed-factor.c create mode 100644 drivers/clk/clk-fixed.c create mode 100644 drivers/clk/clk-mux.c create mode 100644 drivers/clk/clk.c (limited to 'drivers') diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 4168c8896e..66c1c465e8 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -2,3 +2,6 @@ config CLKDEV_LOOKUP bool select HAVE_CLK + +config COMMON_CLK + bool diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 07613fa172..39a75a4e4a 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -1,2 +1,2 @@ - +obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed.o clk-divider.o clk-fixed-factor.o clk-mux.o obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c new file mode 100644 index 0000000000..58a7ea564c --- /dev/null +++ b/drivers/clk/clk-divider.c @@ -0,0 +1,98 @@ +/* + * clk-divider.c - generic barebox clock support. Based on Linux clk support + * + * Copyright (c) 2012 Sascha Hauer , Pengutronix + * + * 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 +#include +#include +#include +#include + +struct clk_divider { + struct clk clk; + u8 shift; + u8 width; + void __iomem *reg; + const char *parent; +}; + +static int clk_divider_set_rate(struct clk *clk, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_divider *div = container_of(clk, struct clk_divider, clk); + unsigned int val, divval; + + if (rate > parent_rate) + rate = parent_rate; + if (!rate) + rate = 1; + + divval = DIV_ROUND_UP(parent_rate, rate); + + if (divval > (1 << div->width)) + divval = 1 << (div->width); + + divval--; + + val = readl(div->reg); + val &= ~(((1 << div->width) - 1) << div->shift); + val |= divval << div->shift; + writel(val, div->reg); + + return 0; +} + +static unsigned long clk_divider_recalc_rate(struct clk *clk, + unsigned long parent_rate) +{ + struct clk_divider *div = container_of(clk, struct clk_divider, clk); + unsigned int val; + + val = readl(div->reg) >> div->shift; + val &= (1 << div->width) - 1; + + val++; + + return parent_rate / val; +} + +struct clk_ops clk_divider_ops = { + .set_rate = clk_divider_set_rate, + .recalc_rate = clk_divider_recalc_rate, +}; + +struct clk *clk_divider(const char *name, const char *parent, + void __iomem *reg, u8 shift, u8 width) +{ + struct clk_divider *div = xzalloc(sizeof(*div)); + int ret; + + div->shift = shift; + div->reg = reg; + div->width = width; + div->parent = parent; + div->clk.ops = &clk_divider_ops; + div->clk.name = name; + div->clk.parent_names = &div->parent; + div->clk.num_parents = 1; + + ret = clk_register(&div->clk); + if (ret) { + free(div); + return ERR_PTR(ret); + } + + return &div->clk; +} diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c new file mode 100644 index 0000000000..52e7c16c49 --- /dev/null +++ b/drivers/clk/clk-fixed-factor.c @@ -0,0 +1,63 @@ +/* + * clk-fixed-factor.c - generic barebox clock support. Based on Linux clk support + * + * Copyright (c) 2012 Sascha Hauer , Pengutronix + * + * 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 +#include +#include +#include +#include + +struct clk_fixed_factor { + struct clk clk; + int mult; + int div; + const char *parent; +}; + +static unsigned long clk_fixed_factor_recalc_rate(struct clk *clk, + unsigned long parent_rate) +{ + struct clk_fixed_factor *f = container_of(clk, struct clk_fixed_factor, clk); + + return (parent_rate / f->div) * f->mult; +} + +struct clk_ops clk_fixed_factor_ops = { + .recalc_rate = clk_fixed_factor_recalc_rate, +}; + +struct clk *clk_fixed_factor(const char *name, + const char *parent, unsigned int mult, unsigned int div) +{ + struct clk_fixed_factor *f = xzalloc(sizeof(*f)); + int ret; + + f->mult = mult; + f->div = div; + f->parent = parent; + f->clk.ops = &clk_fixed_factor_ops; + f->clk.name = name; + f->clk.parent_names = &f->parent; + f->clk.num_parents = 1; + + ret = clk_register(&f->clk); + if (ret) { + free(f); + return ERR_PTR(ret); + } + + return &f->clk; +} diff --git a/drivers/clk/clk-fixed.c b/drivers/clk/clk-fixed.c new file mode 100644 index 0000000000..fa89cb2840 --- /dev/null +++ b/drivers/clk/clk-fixed.c @@ -0,0 +1,55 @@ +/* + * clk-fixed.c - generic barebox clock support. Based on Linux clk support + * + * Copyright (c) 2012 Sascha Hauer , Pengutronix + * + * 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 +#include +#include +#include + +struct clk_fixed { + struct clk clk; + unsigned long rate; +}; + +static unsigned long clk_fixed_recalc_rate(struct clk *clk, + unsigned long parent_rate) +{ + struct clk_fixed *fix = container_of(clk, struct clk_fixed, clk); + + return fix->rate; +} + +struct clk_ops clk_fixed_ops = { + .recalc_rate = clk_fixed_recalc_rate, +}; + +struct clk *clk_fixed(const char *name, int rate) +{ + struct clk_fixed *fix = xzalloc(sizeof *fix); + int ret; + + fix->rate = rate; + fix->clk.ops = &clk_fixed_ops; + fix->clk.name = name; + + ret = clk_register(&fix->clk); + if (ret) { + free(fix); + return ERR_PTR(ret); + } + + return &fix->clk; +} diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c new file mode 100644 index 0000000000..cb5f1a1a7b --- /dev/null +++ b/drivers/clk/clk-mux.c @@ -0,0 +1,77 @@ +/* + * clk-mux.c - generic barebox clock support. Based on Linux clk support + * + * Copyright (c) 2012 Sascha Hauer , Pengutronix + * + * 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 +#include +#include +#include +#include + +struct clk_mux { + struct clk clk; + void __iomem *reg; + int shift; + int width; +}; + +static int clk_mux_get_parent(struct clk *clk) +{ + struct clk_mux *m = container_of(clk, struct clk_mux, clk); + int idx = readl(m->reg) >> m->shift & ((1 << m->width) - 1); + + return idx; +} + +static int clk_mux_set_parent(struct clk *clk, u8 idx) +{ + struct clk_mux *m = container_of(clk, struct clk_mux, clk); + u32 val; + + val = readl(m->reg); + val &= ~(((1 << m->width) - 1) << m->shift); + val |= idx << m->shift; + writel(val, m->reg); + + return 0; +} + +struct clk_ops clk_mux_ops = { + .get_parent = clk_mux_get_parent, + .set_parent = clk_mux_set_parent, +}; + +struct clk *clk_mux(const char *name, void __iomem *reg, + u8 shift, u8 width, const char **parents, u8 num_parents) +{ + struct clk_mux *m = xzalloc(sizeof(*m)); + int ret; + + m->reg = reg; + m->shift = shift; + m->width = width; + m->clk.ops = &clk_mux_ops; + m->clk.name = name; + m->clk.parent_names = parents; + m->clk.num_parents = num_parents; + + ret = clk_register(&m->clk); + if (ret) { + free(m); + return ERR_PTR(ret); + } + + return &m->clk; +} diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c new file mode 100644 index 0000000000..bf61e5db94 --- /dev/null +++ b/drivers/clk/clk.c @@ -0,0 +1,224 @@ +/* + * clk.c - generic barebox clock support. Based on Linux clk support + * + * Copyright (c) 2012 Sascha Hauer , Pengutronix + * + * 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 +#include +#include +#include + +static LIST_HEAD(clks); + +static int clk_parent_enable(struct clk *clk) +{ + struct clk *parent = clk_get_parent(clk); + + if (!IS_ERR_OR_NULL(parent)) + return clk_enable(parent); + + return 0; +} + +static void clk_parent_disable(struct clk *clk) +{ + struct clk *parent = clk_get_parent(clk); + + if (!IS_ERR_OR_NULL(parent)) + clk_disable(parent); +} + +int clk_enable(struct clk *clk) +{ + int ret; + + if (!clk->enable_count) { + ret = clk_parent_enable(clk); + if (ret) + return ret; + + if (clk->ops->enable) { + ret = clk->ops->enable(clk); + if (ret) { + clk_parent_disable(clk); + return ret; + } + } + } + + clk->enable_count++; + + return 0; +} + +void clk_disable(struct clk *clk) +{ + if (!clk->enable_count) + return; + + clk->enable_count--; + + if (!clk->enable_count) { + if (clk->ops->disable) + clk->ops->disable(clk); + + clk_parent_disable(clk); + } +} + +unsigned long clk_get_rate(struct clk *clk) +{ + struct clk *parent; + unsigned long parent_rate = 0; + + parent = clk_get_parent(clk); + if (!IS_ERR_OR_NULL(parent)) + parent_rate = clk_get_rate(parent); + + if (clk->ops->recalc_rate) + return clk->ops->recalc_rate(clk, parent_rate); + + return parent_rate; +} + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return clk_get_rate(clk); +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + struct clk *parent; + unsigned long parent_rate = 0; + + parent = clk_get_parent(clk); + if (parent) + parent_rate = clk_get_rate(parent); + + if (clk->ops->set_rate) + return clk->ops->set_rate(clk, rate, parent_rate); + + return -ENOSYS; +} + +struct clk *clk_lookup(const char *name) +{ + struct clk *c; + + if (!name) + return ERR_PTR(-ENODEV); + + list_for_each_entry(c, &clks, list) { + if (!strcmp(c->name, name)) + return c; + } + + return ERR_PTR(-ENODEV); +} + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + int i; + + if (!clk->num_parents) + return -EINVAL; + if (!clk->ops->set_parent) + return -EINVAL; + + for (i = 0; i < clk->num_parents; i++) { + if (IS_ERR_OR_NULL(clk->parents[i])) + clk->parents[i] = clk_lookup(clk->parent_names[i]); + + if (!IS_ERR_OR_NULL(clk->parents[i])) + if (clk->parents[i] == parent) + break; + } + + if (i == clk->num_parents) + return -EINVAL; + + return clk->ops->set_parent(clk, i); +} + +struct clk *clk_get_parent(struct clk *clk) +{ + int idx; + + if (!clk->num_parents) + return ERR_PTR(-ENODEV); + + if (clk->num_parents != 1) { + if (!clk->ops->get_parent) + return ERR_PTR(-EINVAL); + + idx = clk->ops->get_parent(clk); + + if (idx >= clk->num_parents) + return ERR_PTR(-ENODEV); + } else { + idx = 0; + } + + if (IS_ERR_OR_NULL(clk->parents[idx])) + clk->parents[idx] = clk_lookup(clk->parent_names[idx]); + + return clk->parents[idx]; +} + +int clk_register(struct clk *clk) +{ + clk->parents = xzalloc(sizeof(struct clk *) * clk->num_parents); + + list_add_tail(&clk->list, &clks); + + return 0; +} + +static void dump_one(struct clk *clk, int verbose, int indent) +{ + struct clk *c; + + printf("%*s%s (rate %ld, %sabled)\n", indent * 4, "", clk->name, clk_get_rate(clk), + clk->enable_count ? "en" : "dis"); + if (verbose) { + + if (clk->num_parents > 1) { + int i; + printf("%*s`---- possible parents: ", indent * 4, ""); + for (i = 0; i < clk->num_parents; i++) + printf("%s ", clk->parent_names[i]); + printf("\n"); + } + } + + list_for_each_entry(c, &clks, list) { + struct clk *parent = clk_get_parent(c); + + if (parent == clk) { + dump_one(c, verbose, indent + 1); + } + } +} + +void clk_dump(int verbose) +{ + struct clk *c; + + list_for_each_entry(c, &clks, list) { + struct clk *parent = clk_get_parent(c); + + if (IS_ERR_OR_NULL(parent)) + dump_one(c, verbose, 0); + } +} diff --git a/include/linux/clk.h b/include/linux/clk.h index 1478c97381..e9031dd17a 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -155,4 +155,46 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id); int clk_add_alias(const char *alias, const char *alias_dev_name, char *id, struct device_d *dev); +#ifdef CONFIG_COMMON_CLK +struct clk_ops { + int (*enable)(struct clk *clk); + void (*disable)(struct clk *clk); + int (*is_enabled)(struct clk *clk); + unsigned long (*recalc_rate)(struct clk *clk, + unsigned long parent_rate); + long (*round_rate)(struct clk *clk, unsigned long, + unsigned long *); + int (*set_parent)(struct clk *clk, u8 index); + int (*get_parent)(struct clk *clk); + int (*set_rate)(struct clk *clk, unsigned long, + unsigned long); +}; + +struct clk { + const struct clk_ops *ops; + int enable_count; + struct list_head list; + const char *name; + const char **parent_names; + int num_parents; + + struct clk **parents; +}; + +struct clk *clk_fixed(const char *name, int rate); +struct clk *clk_divider(const char *name, const char *parent, + void __iomem *reg, u8 shift, u8 width); +struct clk *clk_fixed_factor(const char *name, + const char *parent, unsigned int mult, unsigned int div); +struct clk *clk_mux(const char *name, void __iomem *reg, + u8 shift, u8 width, const char **parents, u8 num_parents); + +int clk_register(struct clk *clk); + +struct clk *clk_lookup(const char *name); + +void clk_dump(int verbose); + +#endif + #endif -- cgit v1.2.3 From 70253cbbbbe8d12d857555a65af283ccb8dc07ec Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 20 Sep 2012 22:01:40 +0200 Subject: net fec: Switch to clk support Signed-off-by: Sascha Hauer --- drivers/net/fec_imx.c | 34 +++++++++++++++++++++++++++++++--- drivers/net/fec_imx.h | 1 + 2 files changed, 32 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index 6acf6bdee4..d40eff7afb 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include @@ -43,6 +45,19 @@ 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 */ @@ -54,7 +69,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(((imx_get_fecclk() >> 20) / 5) << 1, + writel(((fec_clk_get_rate(fec) >> 20) / 5) << 1, fec->regs + FEC_MII_SPEED); /* * reading from any PHY's register is done by properly @@ -97,7 +112,7 @@ static int fec_miibus_write(struct mii_bus *bus, int phyAddr, uint32_t phy; /* convenient holder for the PHY */ uint64_t start; - writel(((imx_get_fecclk() >> 20) / 5) << 1, + writel(((fec_clk_get_rate(fec) >> 20) / 5) << 1, fec->regs + FEC_MII_SPEED); reg = regAddr << FEC_MII_DATA_RA_SHIFT; @@ -290,7 +305,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(((imx_get_fecclk() >> 20) / 5) << 1, + writel(((fec_clk_get_rate(fec) >> 20) / 5) << 1, fec->regs + FEC_MII_SPEED); } @@ -612,6 +627,7 @@ static int fec_probe(struct device_d *dev) struct eth_device *edev; struct fec_priv *fec; void *base; + int ret; #ifdef CONFIG_ARCH_IMX27 PCCR0 |= PCCR0_FEC_EN; #endif @@ -628,6 +644,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->regs = dev_request_mem_region(dev, 0); /* Reset chip. */ @@ -682,6 +706,10 @@ static int fec_probe(struct device_d *dev) eth_register(edev); return 0; + +err_free: + free(fec); + return ret; } static void fec_remove(struct device_d *dev) diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h index d10385a531..d147dca113 100644 --- a/drivers/net/fec_imx.h +++ b/drivers/net/fec_imx.h @@ -138,6 +138,7 @@ struct fec_priv { u32 phy_flags; struct mii_bus miibus; void (*phy_init)(struct phy_device *dev); + struct clk *clk; }; /** -- cgit v1.2.3 From e3bc3f751d75d077756b162a5c2b800b0ebfa9fd Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 20 Sep 2012 22:02:06 +0200 Subject: serial i.MX: Switch to clk support Signed-off-by: Sascha Hauer --- drivers/serial/serial_imx.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c index 012ab028a1..96f67122cc 100644 --- a/drivers/serial/serial_imx.c +++ b/drivers/serial/serial_imx.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #define URXD0 0x0 /* Receiver Register */ #define URTX0 0x40 /* Transmitter Register */ @@ -170,16 +172,17 @@ struct imx_serial_priv { int baudrate; struct notifier_block notify; void __iomem *regs; + struct clk *clk; }; -static int imx_serial_reffreq(void __iomem *regs) +static int imx_serial_reffreq(struct imx_serial_priv *priv) { ulong rfdiv; - rfdiv = (readl(regs + UFCR) >> 7) & 7; + rfdiv = (readl(priv->regs + UFCR) >> 7) & 7; rfdiv = rfdiv < 6 ? 6 - rfdiv : 7; - return imx_get_uartclk() / rfdiv; + return clk_get_rate(priv->clk) / rfdiv; } /* @@ -209,7 +212,7 @@ static int imx_serial_init_port(struct console_device *cdev) writel(0xa81, regs + UFCR); #ifdef ONEMS - writel(imx_serial_reffreq(regs) / 1000, regs + ONEMS); + writel(imx_serial_reffreq(priv) / 1000, regs + ONEMS); #endif /* Enable FIFOs */ @@ -291,7 +294,7 @@ static int imx_serial_setbaudrate(struct console_device *cdev, int baudrate) /* Set the numerator value minus one of the BRM ratio */ writel((baudrate / 100) - 1, regs + UBIR); /* Set the denominator value minus one of the BRM ratio */ - writel((imx_serial_reffreq(regs) / 1600) - 1, regs + UBMR); + writel((imx_serial_reffreq(priv) / 1600) - 1, regs + UBMR); writel(ucr1, regs + UCR1); @@ -316,11 +319,18 @@ static int imx_serial_probe(struct device_d *dev) struct console_device *cdev; struct imx_serial_priv *priv; uint32_t val; + int ret; priv = xzalloc(sizeof(*priv)); cdev = &priv->cdev; dev->priv = priv; + priv->clk = clk_get(dev, NULL); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + goto err_free; + } + priv->regs = dev_request_mem_region(dev, 0); cdev->dev = dev; cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR; @@ -343,6 +353,11 @@ static int imx_serial_probe(struct device_d *dev) clock_register_client(&priv->notify); return 0; + +err_free: + free(priv); + + return ret; } static void imx_serial_remove(struct device_d *dev) -- cgit v1.2.3 From 2155161eca0181ecca9862633fbecb853a3f5b99 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 20 Sep 2012 22:02:26 +0200 Subject: spi i.MX: Switch to clk support Signed-off-by: Sascha Hauer --- drivers/spi/imx_spi.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c index c3dc6cc863..0229374f7a 100644 --- a/drivers/spi/imx_spi.c +++ b/drivers/spi/imx_spi.c @@ -21,10 +21,13 @@ #include #include #include +#include #include #include #include #include +#include +#include #define CSPI_0_0_RXDATA 0x00 #define CSPI_0_0_TXDATA 0x04 @@ -128,6 +131,7 @@ struct imx_spi { struct spi_master master; int *cs_array; void __iomem *regs; + struct clk *clk; unsigned int (*xchg_single)(struct imx_spi *imx, u32 data); void (*chipselect)(struct spi_device *spi, int active); @@ -276,7 +280,7 @@ static void cspi_0_7_chipselect(struct spi_device *spi, int is_active) return; } - reg |= spi_imx_clkdiv_2(imx_get_cspiclk(), spi->max_speed_hz) << + reg |= spi_imx_clkdiv_2(clk_get_rate(imx->clk), spi->max_speed_hz) << CSPI_0_7_CTRL_DR_SHIFT; reg |= (spi->bits_per_word - 1) << CSPI_0_7_CTRL_BL_SHIFT; @@ -381,7 +385,7 @@ static void cspi_2_3_chipselect(struct spi_device *spi, int is_active) ctrl |= CSPI_2_3_CTRL_MODE(cs); /* set clock speed */ - ctrl |= cspi_2_3_clkdiv(imx_get_cspiclk(), spi->max_speed_hz); + ctrl |= cspi_2_3_clkdiv(clk_get_rate(imx->clk), spi->max_speed_hz); /* set chip select to use */ ctrl |= CSPI_2_3_CTRL_CS(cs); @@ -524,6 +528,7 @@ static int imx_spi_probe(struct device_d *dev) struct imx_spi *imx; struct spi_imx_master *pdata = dev->platform_data; enum imx_spi_devtype version; + int ret; imx = xzalloc(sizeof(*imx)); @@ -532,6 +537,7 @@ static int imx_spi_probe(struct device_d *dev) master->setup = imx_spi_setup; master->transfer = imx_spi_transfer; + if (pdata) { master->num_chipselect = pdata->num_chipselect; imx->cs_array = pdata->chipselect; @@ -540,6 +546,12 @@ static int imx_spi_probe(struct device_d *dev) imx_spi_dt_probe(imx); } + imx->clk = clk_get(dev, NULL); + if (IS_ERR(imx->clk)) { + ret = PTR_ERR(imx->clk); + goto err_free; + } + #ifdef CONFIG_DRIVER_SPI_IMX_0_0 if (cpu_is_mx27()) version = SPI_IMX_VER_0_0; @@ -562,6 +574,11 @@ static int imx_spi_probe(struct device_d *dev) spi_register_master(master); return 0; + +err_free: + free(imx); + + return ret; } static __maybe_unused struct of_device_id imx_spi_dt_ids[] = { -- cgit v1.2.3 From c7cea55e0ad07fe43973675cfc42b27b20e87a92 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sun, 23 Sep 2012 17:48:32 +0200 Subject: mci i.MX ESDHC: Switch to clock support Signed-off-by: Sascha Hauer --- drivers/mci/imx-esdhc.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c index 7c12eba5da..449fe8dbca 100644 --- a/drivers/mci/imx-esdhc.c +++ b/drivers/mci/imx-esdhc.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -70,6 +72,7 @@ struct fsl_esdhc_host { u32 no_snoop; unsigned long cur_clock; struct device_d *dev; + struct clk *clk; }; #define to_fsl_esdhc(mci) container_of(mci, struct fsl_esdhc_host, mci) @@ -354,7 +357,7 @@ static void set_sysctl(struct mci_host *mci, u32 clock) int div, pre_div; struct fsl_esdhc_host *host = to_fsl_esdhc(mci); struct fsl_esdhc __iomem *regs = host->regs; - int sdhc_clk = imx_get_mmcclk(); + int sdhc_clk = clk_get_rate(host->clk); u32 clk; if (clock < mci->f_min) @@ -516,11 +519,16 @@ static int fsl_esdhc_probe(struct device_d *dev) struct mci_host *mci; u32 caps; int ret; + unsigned long rate; struct esdhc_platform_data *pdata = dev->platform_data; host = xzalloc(sizeof(*host)); mci = &host->mci; + host->clk = clk_get(dev, NULL); + if (IS_ERR(host->clk)) + return PTR_ERR(host->clk); + host->dev = dev; host->regs = dev_request_mem_region(dev, 0); @@ -553,10 +561,11 @@ static int fsl_esdhc_probe(struct device_d *dev) host->mci.init = esdhc_init; host->mci.hw_dev = dev; - host->mci.f_min = imx_get_mmcclk() >> 12; + rate = clk_get_rate(host->clk); + host->mci.f_min = rate >> 12; if (host->mci.f_min < 200000) host->mci.f_min = 200000; - host->mci.f_max = imx_get_mmcclk(); + host->mci.f_max = rate; mci_register(&host->mci); -- cgit v1.2.3 From 3591842f8aa31e9022e3ef97552d590f9aad59c7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sun, 23 Sep 2012 17:51:14 +0200 Subject: mci i.MX: Switch to clock support Signed-off-by: Sascha Hauer --- drivers/mci/imx.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mci/imx.c b/drivers/mci/imx.c index 0e4fa66739..035a3aa279 100644 --- a/drivers/mci/imx.c +++ b/drivers/mci/imx.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include @@ -103,6 +105,7 @@ struct mxcmci_regs { struct mxcmci_host { struct mci_host mci; struct mxcmci_regs *base; + struct clk *clk; int irq; int detect_irq; int dma; @@ -415,7 +418,7 @@ static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios) { unsigned int divider; int prescaler = 0; - unsigned long clk_in = imx_get_mmcclk(); + unsigned long clk_in = clk_get_rate(host->clk); while (prescaler <= 0x800) { for (divider = 1; divider <= 0xF; divider++) { @@ -490,9 +493,14 @@ static int mxcmci_init(struct mci_host *mci, struct device_d *dev) static int mxcmci_probe(struct device_d *dev) { struct mxcmci_host *host; + unsigned long rate; host = xzalloc(sizeof(*host)); + host->clk = clk_get(dev, NULL); + if (IS_ERR(host->clk)) + return PTR_ERR(host->clk); + host->mci.send_cmd = mxcmci_request; host->mci.set_ios = mxcmci_set_ios; host->mci.init = mxcmci_init; @@ -503,8 +511,9 @@ static int mxcmci_probe(struct device_d *dev) host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34; - host->mci.f_min = imx_get_mmcclk() >> 7; - host->mci.f_max = imx_get_mmcclk() >> 1; + rate = clk_get_rate(host->clk); + host->mci.f_min = rate >> 7; + host->mci.f_max = rate >> 1; mci_register(&host->mci); -- cgit v1.2.3 From 8a67a0a035ee512e7cf134fd7829fea824eff533 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sun, 23 Sep 2012 17:58:33 +0200 Subject: i2c i.MX: Switch to clock support Signed-off-by: Sascha Hauer --- drivers/i2c/busses/i2c-imx.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 2ac043b37b..98c06f045f 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -37,7 +37,7 @@ #include #include #include - +#include #include #include @@ -101,6 +101,7 @@ static u16 i2c_clk_div[50][2] = { struct fsl_i2c_struct { void __iomem *base; + struct clk *clk; struct i2c_adapter adapter; unsigned int disable_delay; int stopped; @@ -109,6 +110,19 @@ struct fsl_i2c_struct { }; #define to_fsl_i2c_struct(a) container_of(a, struct fsl_i2c_struct, adapter) +#ifdef CONFIG_COMMON_CLK +static inline unsigned long i2c_fsl_clk_get_rate(struct fsl_i2c_struct *i2c_fsl) +{ + return clk_get_rate(i2c_fsl->clk); +} + +#else +static inline unsigned long i2c_fsl_clk_get_rate(struct fsl_i2c_struct *i2c_fsl) +{ + return fsl_get_i2cclk(); +} +#endif + #ifdef CONFIG_I2C_DEBUG static void i2c_fsl_dump_reg(struct i2c_adapter *adapter) { @@ -344,7 +358,7 @@ static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl, int i; /* Divider value calculation */ - i2c_clk_rate = fsl_get_i2cclk(); + i2c_clk_rate = i2c_fsl_clk_get_rate(i2c_fsl); div = (i2c_clk_rate + rate - 1) / rate; if (div < i2c_clk_div[0][0]) i = 0; @@ -535,6 +549,11 @@ static int __init i2c_fsl_probe(struct device_d *pdev) i2c_fsl = kzalloc(sizeof(struct fsl_i2c_struct), GFP_KERNEL); +#ifdef CONFIG_COMMON_CLK + i2c_fsl->clk = clk_get(pdev, NULL); + if (IS_ERR(i2c_fsl->clk)) + return PTR_ERR(i2c_fsl->clk); +#endif /* Setup i2c_fsl driver structure */ i2c_fsl->adapter.master_xfer = i2c_fsl_xfer; i2c_fsl->adapter.nr = pdev->id; -- cgit v1.2.3 From a0e03bb62f787b428297f647e3ac80bc0262b007 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sun, 23 Sep 2012 20:18:08 +0200 Subject: video i.MX: Switch to clock support Signed-off-by: Sascha Hauer --- drivers/video/imx.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/imx.c b/drivers/video/imx.c index 452e558cfe..810d8e3ab6 100644 --- a/drivers/video/imx.c +++ b/drivers/video/imx.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include @@ -138,6 +140,7 @@ struct imxfb_rgb { struct imxfb_info { void __iomem *regs; + struct clk *clk; u_int pcr; u_int pwmr; @@ -341,7 +344,7 @@ static int imxfb_activate_var(struct fb_info *info) writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1), fbi->regs + LCDC_CPOS); - lcd_clk = imx_get_lcdclk(); + lcd_clk = clk_get_rate(fbi->clk); tmp = mode->pixclock * (unsigned long long)lcd_clk; @@ -564,6 +567,10 @@ static int imxfb_probe(struct device_d *dev) fbi = xzalloc(sizeof(*fbi)); info = &fbi->info; + fbi->clk = clk_get(dev, NULL); + if (IS_ERR(fbi->clk)) + return PTR_ERR(fbi->clk); + fbi->mode = pdata->mode; fbi->regs = dev_request_mem_region(dev, 0); fbi->pcr = pdata->mode->pcr; -- cgit v1.2.3 From 85b1bff1541ee7804ae7f663c5ca386d2ad4d611 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 24 Sep 2012 12:36:02 +0200 Subject: video i.MX IPU: Switch to clock support Signed-off-by: Sascha Hauer --- drivers/video/imx-ipu-fb.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c index 80236b3f23..6343f12d1e 100644 --- a/drivers/video/imx-ipu-fb.c +++ b/drivers/video/imx-ipu-fb.c @@ -27,10 +27,12 @@ #include #include #include -#include +#include +#include struct ipu_fb_info { void __iomem *regs; + struct clk *clk; void (*enable)(int enable); @@ -480,7 +482,7 @@ static int sdc_init_panel(struct fb_info *info, enum pixel_fmt pixel_fmt) * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz */ pixel_clk = PICOS2KHZ(mode->pixclock) * 1000UL; - div = imx_get_lcdclk() * 16 / pixel_clk; + div = clk_get_rate(fbi->clk) * 16 / pixel_clk; if (div < 0x40) { /* Divider less than 4 */ dev_dbg(&info->dev, @@ -986,6 +988,10 @@ static int imxfb_probe(struct device_d *dev) fbi = xzalloc(sizeof(*fbi)); info = &fbi->info; + fbi->clk = clk_get(dev, NULL); + if (IS_ERR(fbi->clk)) + return PTR_ERR(fbi->clk); + fbi->regs = dev_request_mem_region(dev, 0); fbi->dev = dev; fbi->enable = pdata->enable; -- cgit v1.2.3 From d4edd480b2ab0754361b142e307796405310d34b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 24 Sep 2012 12:16:12 +0200 Subject: ARM i.MX: Remove old clock support The old clock support is now unused. Remove it. The former i.MX clko command is superseeded by generic clock manipulation commands. Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Kconfig | 8 - arch/arm/mach-imx/Makefile | 20 +- arch/arm/mach-imx/clko.c | 60 ----- arch/arm/mach-imx/clocksource.c | 1 - arch/arm/mach-imx/include/mach/clock.h | 42 +--- arch/arm/mach-imx/speed-imx1.c | 91 -------- arch/arm/mach-imx/speed-imx21.c | 193 ---------------- arch/arm/mach-imx/speed-imx25.c | 155 ------------- arch/arm/mach-imx/speed-imx27.c | 227 ------------------ arch/arm/mach-imx/speed-imx31.c | 79 ------- arch/arm/mach-imx/speed-imx35.c | 255 --------------------- arch/arm/mach-imx/speed-imx51.c | 311 ------------------------- arch/arm/mach-imx/speed-imx53.c | 236 ------------------- arch/arm/mach-imx/speed-imx6.c | 404 --------------------------------- arch/arm/mach-imx/speed.c | 82 ------- drivers/mci/imx-esdhc.c | 1 - drivers/serial/serial_imx.c | 1 - drivers/spi/imx_spi.c | 1 - drivers/video/imx.c | 1 - 19 files changed, 10 insertions(+), 2158 deletions(-) delete mode 100644 arch/arm/mach-imx/clko.c delete mode 100644 arch/arm/mach-imx/speed-imx1.c delete mode 100644 arch/arm/mach-imx/speed-imx21.c delete mode 100644 arch/arm/mach-imx/speed-imx25.c delete mode 100644 arch/arm/mach-imx/speed-imx27.c delete mode 100644 arch/arm/mach-imx/speed-imx31.c delete mode 100644 arch/arm/mach-imx/speed-imx35.c delete mode 100644 arch/arm/mach-imx/speed-imx51.c delete mode 100644 arch/arm/mach-imx/speed-imx53.c delete mode 100644 arch/arm/mach-imx/speed-imx6.c delete mode 100644 arch/arm/mach-imx/speed.c (limited to 'drivers') diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 7ab812abc5..d27d4f34d5 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -552,14 +552,6 @@ endmenu menu "i.MX specific settings " -config IMX_CLKO - bool "clko command" - depends on ARCH_IMX21 || ARCH_IMX27 || ARCH_IMX35 || ARCH_IMX25 || ARCH_IMX51 - help - The i.MX SoCs have a Pin which can output different reference frequencies. - Say y here if you want to have the clko command which lets you select the - frequency to output on this pin. - config IMX_IIM tristate "IIM fusebox device" depends on !ARCH_IMX21 && !ARCH_IMX21 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index f7a5ba4a3a..e43f92e430 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -1,20 +1,18 @@ obj-y += clocksource.o gpio.o obj-$(CONFIG_RESET_SOURCE) += reset_source.o -obj-$(CONFIG_ARCH_IMX1) += speed-imx1.o imx1.o iomux-v1.o clk-imx1.o -obj-$(CONFIG_ARCH_IMX25) += speed-imx25.o imx25.o iomux-v3.o clk-imx25.o -obj-$(CONFIG_ARCH_IMX21) += speed-imx21.o imx21.o iomux-v1.o clk-imx21.o -obj-$(CONFIG_ARCH_IMX27) += speed-imx27.o imx27.o iomux-v1.o clk-imx27.o -obj-$(CONFIG_ARCH_IMX31) += speed-imx31.o imx31.o iomux-v2.o clk-imx31.o -obj-$(CONFIG_ARCH_IMX35) += speed-imx35.o imx35.o iomux-v3.o clk-imx35.o -obj-$(CONFIG_ARCH_IMX51) += speed-imx51.o imx51.o iomux-v3.o imx5.o clk-imx5.o -obj-$(CONFIG_ARCH_IMX53) += speed-imx53.o imx53.o iomux-v3.o imx5.o clk-imx5.o -obj-$(CONFIG_ARCH_IMX6) += speed-imx6.o imx6.o iomux-v3.o usb-imx6.o clk-imx6.o -obj-$(CONFIG_IMX_CLKO) += clko.o +obj-$(CONFIG_ARCH_IMX1) += imx1.o iomux-v1.o clk-imx1.o +obj-$(CONFIG_ARCH_IMX25) += imx25.o iomux-v3.o clk-imx25.o +obj-$(CONFIG_ARCH_IMX21) += imx21.o iomux-v1.o clk-imx21.o +obj-$(CONFIG_ARCH_IMX27) += imx27.o iomux-v1.o clk-imx27.o +obj-$(CONFIG_ARCH_IMX31) += imx31.o iomux-v2.o clk-imx31.o +obj-$(CONFIG_ARCH_IMX35) += imx35.o iomux-v3.o clk-imx35.o +obj-$(CONFIG_ARCH_IMX51) += imx51.o iomux-v3.o imx5.o clk-imx5.o +obj-$(CONFIG_ARCH_IMX53) += imx53.o iomux-v3.o imx5.o clk-imx5.o +obj-$(CONFIG_ARCH_IMX6) += imx6.o iomux-v3.o usb-imx6.o clk-imx6.o obj-$(CONFIG_IMX_IIM) += iim.o obj-$(CONFIG_NAND_IMX) += nand.o obj-$(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND) += external-nand-boot.o pbl-$(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND) += external-nand-boot.o obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-pfd.o -obj-y += speed.o obj-y += devices.o obj-y += boot.o diff --git a/arch/arm/mach-imx/clko.c b/arch/arm/mach-imx/clko.c deleted file mode 100644 index aeafaa9c41..0000000000 --- a/arch/arm/mach-imx/clko.c +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include -#include - -static int do_clko(int argc, char *argv[]) -{ - int opt, div = 0, src = -2, num = 1, ret; - - while((opt = getopt(argc, argv, "n:d:s:")) > 0) { - switch(opt) { - case 'n': - num = simple_strtoul(optarg, NULL, 0); - break; - case 'd': - div = simple_strtoul(optarg, NULL, 0); - break; - case 's': - src = simple_strtol(optarg, NULL, 0); - break; - } - } - - if (div == 0 && src == -2) - return COMMAND_ERROR_USAGE; - - if (src == -1) { - imx_clko_set_src(num, -1); - return 0; - } - - if (src != -2) - imx_clko_set_src(num, src); - - if (div != 0) { - ret = imx_clko_set_div(num, div); - if (ret < 0) - printf("CLKO-line %i not supported.\n", num); - else if (ret != div) - printf("Divider limited to %d.\n", ret); - } - - return 0; -} - -static __maybe_unused char cmd_clko_help[] = -"Usage: clko [OPTION]...\n" -"Route different signals to the i.MX clko pin\n" -" -n Number of CLKO-line (Default 1)\n" -" -d
Divider\n" -" -s Clock select. See Ref. Manual for valid sources. Use -1\n" -" for disabling clock output\n"; - -BAREBOX_CMD_START(clko) - .cmd = do_clko, - .usage = "Adjust CLKO setting", - BAREBOX_CMD_HELP(cmd_clko_help) -BAREBOX_CMD_END - diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c index df018e68c6..9229fb78c9 100644 --- a/arch/arm/mach-imx/clocksource.c +++ b/arch/arm/mach-imx/clocksource.c @@ -33,7 +33,6 @@ #include #include #include -#include #include /* Part 1: Registers */ diff --git a/arch/arm/mach-imx/include/mach/clock.h b/arch/arm/mach-imx/include/mach/clock.h index f613395768..304a7c885c 100644 --- a/arch/arm/mach-imx/include/mach/clock.h +++ b/arch/arm/mach-imx/include/mach/clock.h @@ -1,41 +1 @@ - -#ifndef __ASM_ARCH_CLOCK_H -#define __ASM_ARCH_CLOCK_H -unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref); - -ulong imx_get_mpllclk(void); - -#ifdef CONFIG_ARCH_IMX27 -ulong imx_get_armclk(void); -#endif -#ifdef CONFIG_ARCH_IMX1 -static inline ulong imx_get_armclk(void) -{ - return imx_get_mpllclk(); -} -#endif - -ulong imx_get_spllclk(void); -ulong imx_get_fclk(void); -ulong imx_get_hclk(void); -ulong imx_get_bclk(void); -ulong imx_get_perclk1(void); -ulong imx_get_perclk2(void); -ulong imx_get_perclk3(void); -ulong imx_get_ahbclk(void); -ulong imx_get_fecclk(void); -ulong imx_get_gptclk(void); -ulong imx_get_uartclk(void); -ulong imx_get_lcdclk(void); -ulong fsl_get_i2cclk(void); -ulong imx_get_mmcclk(void); -ulong imx_get_cspiclk(void); -ulong imx_get_ipgclk(void); -ulong imx_get_usbclk(void); - -int imx_clko_set_div(int num, int div); -void imx_clko_set_src(int num, int src); - -void imx_dump_clocks(void); - -#endif /* __ASM_ARCH_CLOCK_H */ +/* nothing, but some drivers need this include */ diff --git a/arch/arm/mach-imx/speed-imx1.c b/arch/arm/mach-imx/speed-imx1.c deleted file mode 100644 index 2b62f6168f..0000000000 --- a/arch/arm/mach-imx/speed-imx1.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * (c) 2004 Sascha Hauer - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 -#include -#include -#include -#include - -ulong imx_get_spllclk(void) -{ - return imx_decode_pll(SPCTL0, CONFIG_SYSPLL_CLK_FREQ); -} - -ulong imx_get_mpllclk(void) -{ - return imx_decode_pll(MPCTL0, CONFIG_SYSPLL_CLK_FREQ); -} - -ulong imx_get_fclk(void) -{ - return (( CSCR>>15)&1) ? imx_get_mpllclk()>>1 : imx_get_mpllclk(); -} - -ulong imx_get_hclk(void) -{ - u32 bclkdiv = (( CSCR >> 10 ) & 0xf) + 1; - return imx_get_spllclk() / bclkdiv; -} - -ulong imx_get_bclk(void) -{ - return imx_get_hclk(); -} - -ulong imx_get_perclk1(void) -{ - return imx_get_spllclk() / (((PCDR) & 0xf)+1); -} - -ulong imx_get_perclk2(void) -{ - return imx_get_spllclk() / (((PCDR>>4) & 0xf)+1); -} - -ulong imx_get_perclk3(void) -{ - return imx_get_spllclk() / (((PCDR>>16) & 0x7f)+1); -} - -ulong imx_get_uartclk(void) -{ - return imx_get_perclk1(); -} - -ulong imx_get_gptclk(void) -{ - return imx_get_perclk1(); -} - -void imx_dump_clocks(void) -{ - printf("spll: %10ld Hz\n", imx_get_spllclk()); - printf("mpll: %10ld Hz\n", imx_get_mpllclk()); - printf("fclk: %10ld Hz\n", imx_get_fclk()); - printf("hclk: %10ld Hz\n", imx_get_hclk()); - printf("bclk: %10ld Hz\n", imx_get_bclk()); - printf("perclk1: %10ld Hz\n", imx_get_perclk1()); - printf("perclk2: %10ld Hz\n", imx_get_perclk2()); - printf("perclk3: %10ld Hz\n", imx_get_perclk3()); - printf("uart: %10ld Hz\n", imx_get_uartclk()); - printf("gpt: %10ld Hz\n", imx_get_gptclk()); -} - diff --git a/arch/arm/mach-imx/speed-imx21.c b/arch/arm/mach-imx/speed-imx21.c deleted file mode 100644 index b9ecd2fa70..0000000000 --- a/arch/arm/mach-imx/speed-imx21.c +++ /dev/null @@ -1,193 +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. - * - */ - -#include -#include -#include -#include -#include -#include - -#ifndef CLK32 -#define CLK32 32768 -#endif - -static ulong clk_in_32k(void) -{ - return 512 * CLK32; -} - -static ulong clk_in_26m(void) -{ - if (CSCR & CSCR_OSC26M_DIV1P5) { - /* divide by 1.5 */ - return 173333333; - } else { - /* divide by 1 */ - return 26000000; - } -} - -ulong imx_get_mpllclk(void) -{ - ulong cscr = CSCR; - ulong fref; - - if (cscr & CSCR_MCU_SEL) - fref = clk_in_26m(); - else - fref = clk_in_32k(); - - return imx_decode_pll(MPCTL0, fref); -} - -ulong imx_get_fclk(void) -{ - ulong cscr = CSCR; - ulong fref = imx_get_mpllclk(); - ulong div; - - div = ((cscr >> 29) & 0x7) + 1; - - return fref / div; -} - -/* HCLK */ -ulong imx_get_armclk(void) -{ - ulong cscr = CSCR; - ulong fref = imx_get_mpllclk(); - ulong div; - - div = ((cscr >> 10) & 0xF) + 1; - - return fref / div; -} - -ulong imx_get_spllclk(void) -{ - ulong cscr = CSCR; - ulong spctl0; - ulong fref; - - if (cscr & CSCR_SP_SEL) - fref = clk_in_26m(); - else - fref = clk_in_32k(); - - spctl0 = SPCTL0; - SPCTL0 = spctl0; - return imx_decode_pll(spctl0, fref); -} - -static ulong imx_decode_perclk(ulong div) -{ - return imx_get_mpllclk() / div; -} - -static ulong imx_get_nfcclk(void) -{ - ulong fref = imx_get_fclk(); - ulong div = ((PCDR0 >> 12) & 0xF) + 1; - return fref / div; -} - -ulong imx_get_perclk1(void) -{ - return imx_decode_perclk((PCDR1 & 0x3f) + 1); -} - -ulong imx_get_perclk2(void) -{ - return imx_decode_perclk(((PCDR1 >> 8) & 0x3f) + 1); -} - -ulong imx_get_perclk3(void) -{ - return imx_decode_perclk(((PCDR1 >> 16) & 0x3f) + 1); -} - -ulong imx_get_perclk4(void) -{ - return imx_decode_perclk(((PCDR1 >> 24) & 0x3f) + 1); -} - -ulong imx_get_uartclk(void) -{ - return imx_get_perclk1(); -} - -ulong imx_get_gptclk(void) -{ - return imx_decode_perclk((PCDR1 & 0x3f) + 1); -} - -ulong imx_get_lcdclk(void) -{ - return imx_get_perclk3(); -} - -void imx_dump_clocks(void) -{ - uint32_t cid = CID; - - printf("chip id: [%08x]\n", cid); - printf("mpll: %10ld Hz\n", imx_get_mpllclk()); - printf("spll: %10ld Hz\n", imx_get_spllclk()); - printf("arm: %10ld Hz\n", imx_get_armclk()); - printf("fclk: %10ld Hz\n", imx_get_fclk()); - printf("nfcclk: %10ld Hz\n", imx_get_nfcclk()); - printf("perclk1: %10ld Hz\n", imx_get_perclk1()); - printf("perclk2: %10ld Hz\n", imx_get_perclk2()); - printf("perclk3: %10ld Hz\n", imx_get_perclk3()); - printf("perclk4: %10ld Hz\n", imx_get_perclk4()); - printf("clkin26: %10ld Hz\n", clk_in_26m()); -} - -/* - * Set the divider of the CLKO pin (when CLK48DIV_CLKO is chosen). - * Returns the new divider (which may be smaller - * than the desired one) - */ -int imx_clko_set_div(int num, int div) -{ - ulong pcdr; - - if (num != 1) - return -ENODEV; - - div--; - div &= 0x7; - - pcdr = PCDR0 & ~(7 << 5); - pcdr |= div << 5; - PCDR0 = pcdr; - - return div + 1; -} - -/* - * Set the clock source for the CLKO pin - */ -void imx_clko_set_src(int num, int src) -{ - unsigned long ccsr; - - if (src < 0 || num != 1) { - return; - } - - ccsr = CCSR & ~0x1f; - ccsr |= src & 0x1f; - CCSR = ccsr; -} diff --git a/arch/arm/mach-imx/speed-imx25.c b/arch/arm/mach-imx/speed-imx25.c deleted file mode 100644 index 3c85713c4d..0000000000 --- a/arch/arm/mach-imx/speed-imx25.c +++ /dev/null @@ -1,155 +0,0 @@ -#include -#include -#include -#include -#include -#include - -unsigned long imx_get_mpllclk(void) -{ - ulong mpctl = readl(MX25_CCM_BASE_ADDR + CCM_MPCTL); - return imx_decode_pll(mpctl, CONFIG_MX25_HCLK_FREQ); -} - -unsigned long imx_get_upllclk(void) -{ - ulong ppctl = readl(MX25_CCM_BASE_ADDR + CCM_UPCTL); - return imx_decode_pll(ppctl, CONFIG_MX25_HCLK_FREQ); -} - -unsigned long imx_get_armclk(void) -{ - unsigned long rate, cctl; - - cctl = readl(MX25_CCM_BASE_ADDR + CCM_CCTL); - rate = imx_get_mpllclk(); - - if (cctl & (1 << 14)) { - rate *= 3; - rate >>= 2; - } - - return rate / ((cctl >> 30) + 1); -} - -unsigned long imx_get_ahbclk(void) -{ - ulong cctl = readl(MX25_CCM_BASE_ADDR + CCM_CCTL); - return imx_get_armclk() / (((cctl >> 28) & 0x3) + 1); -} - -unsigned long imx_get_ipgclk(void) -{ - return imx_get_ahbclk() / 2; -} - -unsigned long imx_get_gptclk(void) -{ - return imx_get_ipgclk(); -} - -unsigned long imx_get_perclk(int per) -{ - ulong ofs = (per & 0x3) * 8; - ulong reg = per & ~0x3; - ulong val = (readl(MX25_CCM_BASE_ADDR + CCM_PCDR0 + reg) >> ofs) & 0x3f; - ulong fref; - - if (readl(MX25_CCM_BASE_ADDR + 0x64) & (1 << per)) - fref = imx_get_upllclk(); - else - fref = imx_get_ahbclk(); - - return fref / (val + 1); -} - -unsigned long imx_get_uartclk(void) -{ - return imx_get_perclk(15); -} - -unsigned long imx_get_fecclk(void) -{ - return imx_get_ipgclk(); -} - -unsigned long imx_get_lcdclk(void) -{ - return imx_get_perclk(7); -} - -unsigned long fsl_get_i2cclk(void) -{ - return imx_get_perclk(6); -} - -unsigned long imx_get_mmcclk(void) -{ - return imx_get_perclk(3); -} - -unsigned long imx_get_cspiclk(void) -{ - return imx_get_ipgclk(); -} - -void imx_dump_clocks(void) -{ - printf("mpll: %10ld Hz\n", imx_get_mpllclk()); - printf("upll: %10ld Hz\n", imx_get_upllclk()); - printf("arm: %10ld Hz\n", imx_get_armclk()); - printf("ahb: %10ld Hz\n", imx_get_ahbclk()); - printf("uart: %10ld Hz\n", imx_get_perclk(15)); - printf("gpt: %10ld Hz\n", imx_get_ipgclk()); - printf("nand: %10ld Hz\n", imx_get_perclk(8)); - printf("lcd: %10ld Hz\n", imx_get_perclk(7)); - printf("i2c: %10ld Hz\n", imx_get_perclk(6)); - printf("sdhc1: %10ld Hz\n", imx_get_perclk(3)); -} - -/* - * Set the divider of the CLKO pin. Returns - * the new divider (which may be smaller - * than the desired one) - */ -int imx_clko_set_div(int num, int div) -{ - unsigned long mcr = readl(MX25_CCM_BASE_ADDR + 0x64); - - if (num != 1) - return -ENODEV; - - div -= 1; - div &= 0x3f; - - mcr &= ~(0x3f << 24); - mcr |= div << 24; - - writel(mcr, MX25_CCM_BASE_ADDR + 0x64); - - return div + 1; -} - -/* - * Set the clock source for the CLKO pin - */ -void imx_clko_set_src(int num, int src) -{ - unsigned long mcr = readl(MX25_CCM_BASE_ADDR + 0x64); - - if (num != 1) - return; - - if (src < 0) { - mcr &= ~(1 << 30); - writel(mcr, MX25_CCM_BASE_ADDR + 0x64); - return; - } - - mcr |= 1 << 30; - mcr &= ~(0xf << 20); - mcr |= (src & 0xf) << 20; - - writel(mcr, MX25_CCM_BASE_ADDR + 0x64); -} - diff --git a/arch/arm/mach-imx/speed-imx27.c b/arch/arm/mach-imx/speed-imx27.c deleted file mode 100644 index 33ec4487b6..0000000000 --- a/arch/arm/mach-imx/speed-imx27.c +++ /dev/null @@ -1,227 +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. - * - */ - -#include -#include -#include -#include -#include -#include - -#ifndef CLK32 -#define CLK32 32000 -#endif - -static ulong clk_in_32k(void) -{ - return 1024 * CLK32; -} - -static ulong clk_in_26m(void) -{ - if (CSCR & CSCR_OSC26M_DIV1P5) { - /* divide by 1.5 */ - return 173333333; - } else { - /* divide by 1 */ - return 26000000; - } -} - -ulong imx_get_mpllclk(void) -{ - ulong cscr = CSCR; - ulong fref; - - if (cscr & CSCR_MCU_SEL) - fref = clk_in_26m(); - else - fref = clk_in_32k(); - - return imx_decode_pll(MPCTL0, fref); -} - -ulong imx_get_armclk(void) -{ - ulong cscr = CSCR; - ulong fref = imx_get_mpllclk(); - ulong div; - - if (!(cscr & CSCR_ARM_SRC_MPLL) && - (imx_silicon_revision() != IMX27_CHIP_REVISION_1_0)) - fref = (fref * 2) / 3; - - div = ((cscr >> 12) & 0x3) + 1; - - return fref / div; -} - -ulong imx_get_ahbclk(void) -{ - ulong cscr = CSCR; - ulong fref = imx_get_mpllclk(); - ulong div; - - if (imx_silicon_revision() == IMX27_CHIP_REVISION_1_0) - div = ((cscr >> 9) & 0xf) + 1; - else - div = ((cscr >> 8) & 0x3) + 1; - - return ((fref * 2) / 3) / div; -} - -ulong imx_get_ipgclk(void) -{ - ulong clk = imx_get_ahbclk(); - - return clk >> 1; -} - -ulong imx_get_fecclk(void) -{ - return imx_get_ipgclk(); -} - -ulong imx_get_spllclk(void) -{ - ulong cscr = CSCR; - ulong spctl0; - ulong fref; - - if (cscr & CSCR_SP_SEL) - fref = clk_in_26m(); - else - fref = clk_in_32k(); - - spctl0 = SPCTL0; - SPCTL0 = spctl0; - return imx_decode_pll(spctl0, fref); -} - -static ulong imx_decode_perclk(ulong div) -{ - if (imx_silicon_revision() == IMX27_CHIP_REVISION_1_0) - return imx_get_mpllclk() / div; - else - return (imx_get_mpllclk() * 2) / (div * 3); -} - -ulong imx_get_perclk1(void) -{ - return imx_decode_perclk((PCDR1 & 0x3f) + 1); -} - -ulong imx_get_perclk2(void) -{ - return imx_decode_perclk(((PCDR1 >> 8) & 0x3f) + 1); -} - -ulong imx_get_perclk3(void) -{ - return imx_decode_perclk(((PCDR1 >> 16) & 0x3f) + 1); -} - -ulong imx_get_perclk4(void) -{ - return imx_decode_perclk(((PCDR1 >> 24) & 0x3f) + 1); -} - -ulong imx_get_uartclk(void) -{ - return imx_get_perclk1(); -} - -ulong imx_get_gptclk(void) -{ - return imx_decode_perclk((PCDR1 & 0x3f) + 1); -} - -ulong imx_get_lcdclk(void) -{ - return imx_get_perclk3(); -} - -ulong fsl_get_i2cclk(void) -{ - return imx_get_ipgclk(); -} - -ulong imx_get_mmcclk(void) -{ - return imx_get_perclk2(); -} - -void imx_dump_clocks(void) -{ - uint32_t cid = CID; - - printf("chip id: [%d,%03x,%d,%03x]\n", - (cid >> 28) & 0xf, (cid >> 16) & 0xfff, - (cid >> 12) & 0xf, (cid >> 0) & 0xfff); - - printf("mpll: %10ld Hz\n", imx_get_mpllclk()); - printf("spll: %10ld Hz\n", imx_get_spllclk()); - printf("arm: %10ld Hz\n", imx_get_armclk()); - printf("perclk1: %10ld Hz\n", imx_get_perclk1()); - printf("perclk2: %10ld Hz\n", imx_get_perclk2()); - printf("perclk3: %10ld Hz\n", imx_get_perclk3()); - printf("perclk4: %10ld Hz\n", imx_get_perclk4()); - printf("clkin26: %10ld Hz\n", clk_in_26m()); - printf("ahb: %10ld Hz\n", imx_get_ahbclk()); - printf("ipg: %10ld Hz\n", imx_get_ipgclk()); -} - -/* - * Set the divider of the CLKO pin. Returns - * the new divider (which may be smaller - * than the desired one) - */ -int imx_clko_set_div(int num, int div) -{ - ulong pcdr; - - if (num != 1) - return -ENODEV; - - div--; - div &= 0x7; - - pcdr = PCDR0 & ~(7 << 22); - pcdr |= div << 22; - PCDR0 = pcdr; - - return div + 1; -} - -/* - * Set the clock source for the CLKO pin - */ -void imx_clko_set_src(int num, int src) -{ - unsigned long ccsr; - - if (num != 1) - return; - - if (src < 0) { - PCDR0 &= ~(1 << 25); - return; - } - - ccsr = CCSR & ~0x1f; - ccsr |= src & 0x1f; - CCSR = ccsr; - - PCDR0 |= (1 << 25); -} - diff --git a/arch/arm/mach-imx/speed-imx31.c b/arch/arm/mach-imx/speed-imx31.c deleted file mode 100644 index f8f73c18b1..0000000000 --- a/arch/arm/mach-imx/speed-imx31.c +++ /dev/null @@ -1,79 +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. - * - */ - -#include -#include -#include -#include -#include - -ulong imx_get_mpl_dpdgck_clk(void) -{ - ulong infreq; - - if ((readl(MX31_CCM_BASE_ADDR + CCM_CCMR) & CCMR_PRCS_MASK) == CCMR_FPM) - infreq = CONFIG_MX31_CLK32 * 1024; - else - infreq = CONFIG_MX31_HCLK_FREQ; - - return imx_decode_pll(readl(MX31_CCM_BASE_ADDR + CCM_MPCTL), infreq); -} - -ulong imx_get_mcu_main_clk(void) -{ - /* For now we assume mpl_dpdgck_clk == mcu_main_clk - * which should be correct for most boards - */ - return imx_get_mpl_dpdgck_clk(); -} - -/** - * Calculate the current pixel clock speed (aka HSP or IPU) - * @return 0 on failure or current frequency in Hz - */ -ulong imx_get_lcdclk(void) -{ - ulong hsp_podf = (readl(MX31_CCM_BASE_ADDR + CCM_PDR0) >> 11) & 0x03; - ulong base_clk = imx_get_mcu_main_clk(); - - return base_clk / (hsp_podf + 1); -} - -ulong imx_get_perclk1(void) -{ - u32 freq = imx_get_mcu_main_clk(); - u32 pdr0 = readl(MX31_CCM_BASE_ADDR + CCM_PDR0); - - freq /= ((pdr0 >> 3) & 0x7) + 1; - freq /= ((pdr0 >> 6) & 0x3) + 1; - - return freq; -} - -void imx_dump_clocks(void) -{ - ulong cpufreq = imx_get_mcu_main_clk(); - printf("mx31 cpu clock: %ldMHz\n",cpufreq / 1000000); - printf("ipg clock : %ldHz\n", imx_get_perclk1()); -} - -ulong imx_get_uartclk(void) -{ - return imx_get_perclk1(); -} - -ulong imx_get_gptclk(void) -{ - return imx_get_perclk1(); -} - diff --git a/arch/arm/mach-imx/speed-imx35.c b/arch/arm/mach-imx/speed-imx35.c deleted file mode 100644 index a8063f20b3..0000000000 --- a/arch/arm/mach-imx/speed-imx35.c +++ /dev/null @@ -1,255 +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. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -unsigned long imx_get_mpllclk(void) -{ - ulong mpctl = readl(MX35_CCM_BASE_ADDR + CCM_MPCTL); - return imx_decode_pll(mpctl, CONFIG_MX35_HCLK_FREQ); -} - -static unsigned long imx_get_ppllclk(void) -{ - ulong ppctl = readl(MX35_CCM_BASE_ADDR + CCM_PPCTL); - return imx_decode_pll(ppctl, CONFIG_MX35_HCLK_FREQ); -} - -struct arm_ahb_div { - unsigned char arm, ahb, sel; -}; - -static struct arm_ahb_div clk_consumer[] = { - { .arm = 1, .ahb = 4, .sel = 0}, - { .arm = 1, .ahb = 3, .sel = 1}, - { .arm = 2, .ahb = 2, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 4, .ahb = 1, .sel = 0}, - { .arm = 1, .ahb = 5, .sel = 0}, - { .arm = 1, .ahb = 8, .sel = 0}, - { .arm = 1, .ahb = 6, .sel = 1}, - { .arm = 2, .ahb = 4, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 4, .ahb = 2, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, -}; - -static unsigned long imx_get_armclk(void) -{ - unsigned long pdr0 = readl(MX35_CCM_BASE_ADDR + CCM_PDR0); - struct arm_ahb_div *aad; - unsigned long fref = imx_get_mpllclk(); - - /* consumer path is selected */ - aad = &clk_consumer[(pdr0 >> 16) & 0xf]; - if (aad->sel) - fref = fref * 3 / 4; - - return fref / aad->arm; -} - -unsigned long imx_get_ahbclk(void) -{ - unsigned long pdr0 = readl(MX35_CCM_BASE_ADDR + CCM_PDR0); - struct arm_ahb_div *aad; - unsigned long fref = imx_get_mpllclk(); - - aad = &clk_consumer[(pdr0 >> 16) & 0xf]; - if (aad->sel) - fref = fref * 3 / 4; - - return fref / aad->ahb; -} - -unsigned long imx_get_ipgclk(void) -{ - ulong clk = imx_get_ahbclk(); - - return clk >> 1; -} - -static unsigned long get_3_3_div(unsigned long in) -{ - return (((in >> 3) & 0x7) + 1) * ((in & 0x7) + 1); -} - -static unsigned long get_6_div(unsigned long in) -{ - return ((in & 0x3f) + 1); -} - -static unsigned long imx_get_ipg_perclk(void) -{ - ulong pdr0 = readl(MX35_CCM_BASE_ADDR + CCM_PDR0); - ulong pdr4 = readl(MX35_CCM_BASE_ADDR + CCM_PDR4); - ulong div; - ulong fref; - - if (pdr0 & PDR0_PER_SEL) { - /* perclk from arm high frequency clock and synched with AHB clki */ - fref = imx_get_armclk(); - div = get_3_3_div((pdr4 >> 16)); - } else { - /* perclk from AHB divided clock */ - fref = imx_get_ahbclk(); - div = ((pdr0 >> 12) & 0x7) + 1; - } - - return fref / div; -} - -unsigned long imx_get_gptclk(void) -{ - return imx_get_ipgclk(); -} - -/** - * Calculate the current pixel clock speed (aka HSP or IPU) - * @return 0 on failure or current frequency in Hz - */ -unsigned long imx_get_lcdclk(void) -{ - unsigned long hsp_podf = (readl(MX35_CCM_BASE_ADDR + CCM_PDR0) >> 20) & 0x03; - unsigned long base_clk = imx_get_armclk(); - - if (base_clk > 400 * 1000 * 1000) { - switch(hsp_podf) { - case 0: - return base_clk >> 2; - case 1: - return base_clk >> 3; - case 2: - return base_clk / 3; - } - } else { - switch(hsp_podf) { - case 0: - case 2: - return base_clk / 3; - case 1: - return base_clk / 6; - } - } - - return 0; -} - -unsigned long imx_get_uartclk(void) -{ - unsigned long pdr3 = readl(MX35_CCM_BASE_ADDR + CCM_PDR3); - unsigned long pdr4 = readl(MX35_CCM_BASE_ADDR + CCM_PDR4); - unsigned long div = get_3_3_div(pdr4 >> 10); - - if (pdr3 & (1 << 14)) - return imx_get_armclk() / div; - else - return imx_get_ppllclk() / div; -} - -/* mmc0 clk only */ -unsigned long imx_get_mmcclk(void) -{ - unsigned long pdr3 = readl(MX35_CCM_BASE_ADDR + CCM_PDR3); - unsigned long div = get_6_div(pdr3); - - if (pdr3 & (1 << 6)) - return imx_get_armclk() / div; - else - return imx_get_ppllclk() / div; -} - -ulong imx_get_fecclk(void) -{ - return imx_get_ipgclk(); -} - -ulong fsl_get_i2cclk(void) -{ - return imx_get_ipg_perclk(); -} - -unsigned long imx_get_cspiclk(void) -{ - return imx_get_ipgclk(); -} - -void imx_dump_clocks(void) -{ - printf("mpll: %10ld Hz\n", imx_get_mpllclk()); - printf("ppll: %10ld Hz\n", imx_get_ppllclk()); - printf("arm: %10ld Hz\n", imx_get_armclk()); - printf("gpt: %10ld Hz\n", imx_get_gptclk()); - printf("ahb: %10ld Hz\n", imx_get_ahbclk()); - printf("ipg: %10ld Hz\n", imx_get_ipgclk()); - printf("ipg_per: %10ld Hz\n", imx_get_ipg_perclk()); - printf("uart: %10ld Hz\n", imx_get_uartclk()); - printf("sdhc1: %10ld Hz\n", imx_get_mmcclk()); -} - -/* - * Set the divider of the CLKO pin. Returns - * the new divider (which may be smaller - * than the desired one) - */ -int imx_clko_set_div(int num, int div) -{ - unsigned long cosr = readl(MX35_CCM_BASE_ADDR + CCM_COSR); - - if (num != 1) - return -ENODEV; - - div -= 1; - div &= 0x3f; - - cosr &= ~(0x3f << 10); - cosr |= div << 10; - - writel(cosr, MX35_CCM_BASE_ADDR + CCM_COSR); - - return div + 1; -} - -/* - * Set the clock source for the CLKO pin - */ -void imx_clko_set_src(int num, int src) -{ - unsigned long cosr = readl(MX35_CCM_BASE_ADDR + CCM_COSR); - - if (num != 1) - return; - - if (src < 0) { - cosr &= ~(1 << 5); - writel(cosr, MX35_CCM_BASE_ADDR + CCM_COSR); - return; - } - - cosr |= 1 << 5; - cosr &= ~0x1f; - cosr &= ~(1 << 6); - cosr |= src & 0x1f; - - writel(cosr, MX35_CCM_BASE_ADDR + CCM_COSR); -} - diff --git a/arch/arm/mach-imx/speed-imx51.c b/arch/arm/mach-imx/speed-imx51.c deleted file mode 100644 index 3903afc821..0000000000 --- a/arch/arm/mach-imx/speed-imx51.c +++ /dev/null @@ -1,311 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static u32 ccm_readl(u32 ofs) -{ - return readl(IOMEM(MX51_CCM_BASE_ADDR) + ofs); -} - -static void ccm_writel(u32 val, u32 ofs) -{ - writel(val, MX51_CCM_BASE_ADDR + ofs); -} - -static unsigned long ckil_get_rate(void) -{ - return 32768; -} - -static unsigned long osc_get_rate(void) -{ - return 24000000; -} - -static unsigned long fpm_get_rate(void) -{ - return ckil_get_rate() * 512; -} - -static unsigned long lp_apm_get_rate(void) -{ - if (ccm_readl(MX5_CCM_CCSR) & MX5_CCM_CCSR_LP_APM_SEL) - return fpm_get_rate(); - else - return osc_get_rate(); -} - -static unsigned long pll_get_rate(void __iomem *pllbase) -{ - long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; - unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl; - u64 temp; - unsigned long parent_rate; - - dp_ctl = readl(pllbase + MX5_PLL_DP_CTL); - - if ((dp_ctl & MX5_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0) - parent_rate = fpm_get_rate(); - else - parent_rate = osc_get_rate(); - - pll_hfsm = dp_ctl & MX5_PLL_DP_CTL_HFSM; - dbl = dp_ctl & MX5_PLL_DP_CTL_DPDCK0_2_EN; - - if (pll_hfsm == 0) { - dp_op = readl(pllbase + MX5_PLL_DP_OP); - dp_mfd = readl(pllbase + MX5_PLL_DP_MFD); - dp_mfn = readl(pllbase + MX5_PLL_DP_MFN); - } else { - dp_op = readl(pllbase + MX5_PLL_DP_HFS_OP); - dp_mfd = readl(pllbase + MX5_PLL_DP_HFS_MFD); - dp_mfn = readl(pllbase + MX5_PLL_DP_HFS_MFN); - } - pdf = dp_op & MX5_PLL_DP_OP_PDF_MASK; - mfi = (dp_op & MX5_PLL_DP_OP_MFI_MASK) >> MX5_PLL_DP_OP_MFI_OFFSET; - mfi = (mfi <= 5) ? 5 : mfi; - mfd = dp_mfd & MX5_PLL_DP_MFD_MASK; - mfn = mfn_abs = dp_mfn & MX5_PLL_DP_MFN_MASK; - /* Sign extend to 32-bits */ - if (mfn >= 0x04000000) { - mfn |= 0xFC000000; - mfn_abs = -mfn; - } - - ref_clk = 2 * parent_rate; - if (dbl != 0) - ref_clk *= 2; - - ref_clk /= (pdf + 1); - temp = (u64)ref_clk * mfn_abs; - do_div(temp, mfd + 1); - if (mfn < 0) - temp = -temp; - temp = (ref_clk * mfi) + temp; - - return temp; -} - -static unsigned long pll1_main_get_rate(void) -{ - return pll_get_rate((void __iomem *)MX51_PLL1_BASE_ADDR); -} - -static unsigned long pll2_sw_get_rate(void) -{ - return pll_get_rate((void __iomem *)MX51_PLL2_BASE_ADDR); -} - -static unsigned long pll3_sw_get_rate(void) -{ - return pll_get_rate((void __iomem *)MX51_PLL3_BASE_ADDR); -} - -static unsigned long get_rate_select(int select, - unsigned long (* get_rate1)(void), - unsigned long (* get_rate2)(void), - unsigned long (* get_rate3)(void), - unsigned long (* get_rate4)(void)) -{ - switch (select) { - case 0: - return get_rate1 ? get_rate1() : 0; - case 1: - return get_rate2 ? get_rate2() : 0; - case 2: - return get_rate3 ? get_rate3() : 0; - case 3: - return get_rate4 ? get_rate4() : 0; - } - - return 0; -} - -unsigned long imx_get_uartclk(void) -{ - u32 reg, prediv, podf; - unsigned long parent_rate; - - reg = ccm_readl(MX5_CCM_CSCMR1); - reg &= MX5_CCM_CSCMR1_UART_CLK_SEL_MASK; - reg >>= MX5_CCM_CSCMR1_UART_CLK_SEL_OFFSET; - - parent_rate = get_rate_select(reg, - pll1_main_get_rate, - pll2_sw_get_rate, - pll3_sw_get_rate, - lp_apm_get_rate); - - reg = ccm_readl(MX5_CCM_CSCDR1); - prediv = ((reg & MX5_CCM_CSCDR1_UART_CLK_PRED_MASK) >> - MX5_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1; - podf = ((reg & MX5_CCM_CSCDR1_UART_CLK_PODF_MASK) >> - MX5_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1; - - return parent_rate / (prediv * podf); -} - -unsigned long imx_get_ahbclk(void) -{ - u32 reg, div; - - reg = ccm_readl(MX5_CCM_CBCDR); - div = ((reg >> 10) & 0x7) + 1; - - return pll2_sw_get_rate() / div; -} - -unsigned long imx_get_ipgclk(void) -{ - u32 reg, div; - - reg = ccm_readl(MX5_CCM_CBCDR); - div = ((reg >> 8) & 0x3) + 1; - - return imx_get_ahbclk() / div; -} - -unsigned long imx_get_gptclk(void) -{ - return imx_get_ipgclk(); -} - -unsigned long imx_get_fecclk(void) -{ - return imx_get_ipgclk(); -} - -unsigned long fsl_get_i2cclk(void) -{ - return imx_get_ipgclk(); -} - -unsigned long imx_get_mmcclk(void) -{ - u32 reg, prediv, podf, rate; - - reg = ccm_readl(MX5_CCM_CSCMR1); - reg &= MX5_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK; - reg >>= MX5_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET; - rate = get_rate_select(reg, - pll1_main_get_rate, - pll2_sw_get_rate, - pll3_sw_get_rate, - lp_apm_get_rate); - - reg = ccm_readl(MX5_CCM_CSCDR1); - prediv = ((reg & MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK) >> - MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET) + 1; - podf = ((reg & MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK) >> - MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET) + 1; - - return rate / (prediv * podf); -} - -unsigned long imx_get_usbclk(void) -{ - u32 reg, prediv, podf, rate; - - reg = ccm_readl(MX5_CCM_CSCMR1); - reg &= MX5_CCM_CSCMR1_USBOH3_CLK_SEL_MASK; - reg >>= MX5_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET; - rate = get_rate_select(reg, - pll1_main_get_rate, - pll2_sw_get_rate, - pll3_sw_get_rate, - lp_apm_get_rate); - - reg = ccm_readl(MX5_CCM_CSCDR1); - prediv = ((reg & MX5_CCM_CSCDR1_USBOH3_CLK_PRED_MASK) >> - MX5_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET) + 1; - podf = ((reg & MX5_CCM_CSCDR1_USBOH3_CLK_PODF_MASK) >> - MX5_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET) + 1; - - return rate / (prediv * podf); -} - -unsigned long imx_get_cspiclk(void) -{ - return 166000000; /* FIXME: bogus value */ -} - -/* - * Set the divider of the CLKO pin. Returns - * the new divider (which may be smaller - * than the desired one) - */ -int imx_clko_set_div(int num, int div) -{ - u32 ccosr = ccm_readl(MX5_CCM_CCOSR); - - div--; - - switch (num) { - case 1: - div &= 0x7; - ccosr &= ~(0x7 << 4); - ccosr |= div << 4; - ccm_writel(ccosr, MX5_CCM_CCOSR); - break; - case 2: - div &= 0x7; - ccosr &= ~(0x7 << 21); - ccosr |= div << 21; - ccm_writel(ccosr, MX5_CCM_CCOSR); - break; - default: - return -ENODEV; - } - - return div + 1; -} - -/* - * Set the clock source for the CLKO pin - */ -void imx_clko_set_src(int num, int src) -{ - u32 ccosr = ccm_readl(MX5_CCM_CCOSR); - - switch (num) { - case 1: - if (src < 0) { - ccosr &= ~(1 << 7); - break; - } - ccosr &= ~0xf; - ccosr |= src & 0xf; - ccosr |= 1 << 7; - break; - case 2: - if (src < 0) { - ccosr &= ~(1 << 24); - break; - } - ccosr &= ~(0x1f << 16); - ccosr |= (src & 0x1f) << 16; - ccosr |= 1 << 24; - break; - default: - return; - } - - ccm_writel(ccosr, MX5_CCM_CCOSR); -} - -void imx_dump_clocks(void) -{ - printf("pll1: %ld\n", pll1_main_get_rate()); - printf("pll2: %ld\n", pll2_sw_get_rate()); - printf("pll3: %ld\n", pll3_sw_get_rate()); - printf("lp_apm: %ld\n", lp_apm_get_rate()); - printf("uart: %ld\n", imx_get_uartclk()); - printf("ipg: %ld\n", imx_get_ipgclk()); - printf("fec: %ld\n", imx_get_fecclk()); - printf("gpt: %ld\n", imx_get_gptclk()); - printf("usb: %ld\n", imx_get_usbclk()); -} diff --git a/arch/arm/mach-imx/speed-imx53.c b/arch/arm/mach-imx/speed-imx53.c deleted file mode 100644 index b1ba5fd1d2..0000000000 --- a/arch/arm/mach-imx/speed-imx53.c +++ /dev/null @@ -1,236 +0,0 @@ -#include -#include -#include -#include -#include -#include "mach/clock-imx51_53.h" - -static u32 ccm_readl(u32 ofs) -{ - return readl(MX53_CCM_BASE_ADDR + ofs); -} - -static unsigned long ckil_get_rate(void) -{ - return 32768; -} - -static unsigned long osc_get_rate(void) -{ - return 24000000; -} - -static unsigned long fpm_get_rate(void) -{ - return ckil_get_rate() * 512; -} - -static unsigned long pll_get_rate(void __iomem *pllbase) -{ - long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; - unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl; - u64 temp; - unsigned long parent_rate; - - dp_ctl = readl(pllbase + MX5_PLL_DP_CTL); - - if ((dp_ctl & MX5_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0) - parent_rate = fpm_get_rate(); - else - parent_rate = osc_get_rate(); - - pll_hfsm = dp_ctl & MX5_PLL_DP_CTL_HFSM; - dbl = dp_ctl & MX5_PLL_DP_CTL_DPDCK0_2_EN; - - if (pll_hfsm == 0) { - dp_op = readl(pllbase + MX5_PLL_DP_OP); - dp_mfd = readl(pllbase + MX5_PLL_DP_MFD); - dp_mfn = readl(pllbase + MX5_PLL_DP_MFN); - } else { - dp_op = readl(pllbase + MX5_PLL_DP_HFS_OP); - dp_mfd = readl(pllbase + MX5_PLL_DP_HFS_MFD); - dp_mfn = readl(pllbase + MX5_PLL_DP_HFS_MFN); - } - pdf = dp_op & MX5_PLL_DP_OP_PDF_MASK; - mfi = (dp_op & MX5_PLL_DP_OP_MFI_MASK) >> MX5_PLL_DP_OP_MFI_OFFSET; - mfi = (mfi <= 5) ? 5 : mfi; - mfd = dp_mfd & MX5_PLL_DP_MFD_MASK; - mfn = mfn_abs = dp_mfn & MX5_PLL_DP_MFN_MASK; - /* Sign extend to 32-bits */ - if (mfn >= 0x04000000) { - mfn |= 0xFC000000; - mfn_abs = -mfn; - } - - ref_clk = 2 * parent_rate; - if (dbl != 0) - ref_clk *= 2; - - ref_clk /= (pdf + 1); - temp = (u64)ref_clk * mfn_abs; - do_div(temp, mfd + 1); - if (mfn < 0) - temp = -temp; - temp = (ref_clk * mfi) + temp; - - return temp; -} - -static unsigned long pll1_main_get_rate(void) -{ - return pll_get_rate((void __iomem *)MX53_PLL1_BASE_ADDR); -} - -static unsigned long pll2_sw_get_rate(void) -{ - return pll_get_rate((void __iomem *)MX53_PLL2_BASE_ADDR); -} - -static unsigned long pll3_sw_get_rate(void) -{ - return pll_get_rate((void __iomem *)MX53_PLL3_BASE_ADDR); -} - -static unsigned long pll4_sw_get_rate(void) -{ - return pll_get_rate((void __iomem *)MX53_PLL4_BASE_ADDR); -} - -static unsigned long get_rate_select(int select, - unsigned long (* get_rate1)(void), - unsigned long (* get_rate2)(void), - unsigned long (* get_rate3)(void), - unsigned long (* get_rate4)(void)) -{ - switch (select) { - case 0: - return get_rate1 ? get_rate1() : 0; - case 1: - return get_rate2 ? get_rate2() : 0; - case 2: - return get_rate3 ? get_rate3() : 0; - case 3: - return get_rate4 ? get_rate4() : 0; - } - - return 0; -} - -unsigned long imx_get_uartclk(void) -{ - u32 reg, prediv, podf; - unsigned long parent_rate; - - reg = ccm_readl(MX5_CCM_CSCMR1); - reg &= MX5_CCM_CSCMR1_UART_CLK_SEL_MASK; - reg >>= MX5_CCM_CSCMR1_UART_CLK_SEL_OFFSET; - - parent_rate = get_rate_select(reg, - pll1_main_get_rate, - pll2_sw_get_rate, - pll3_sw_get_rate, - pll4_sw_get_rate); - - reg = ccm_readl(MX5_CCM_CSCDR1); - prediv = ((reg & MX5_CCM_CSCDR1_UART_CLK_PRED_MASK) >> - MX5_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1; - podf = ((reg & MX5_CCM_CSCDR1_UART_CLK_PODF_MASK) >> - MX5_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1; - - return parent_rate / (prediv * podf); -} - -unsigned long imx_get_ahbclk(void) -{ - u32 reg, div; - - reg = ccm_readl(MX5_CCM_CBCDR); - div = ((reg >> 10) & 0x7) + 1; - - return pll2_sw_get_rate() / div; -} - -unsigned long imx_get_ipgclk(void) -{ - u32 reg, div; - - reg = ccm_readl(MX5_CCM_CBCDR); - div = ((reg >> 8) & 0x3) + 1; - - return imx_get_ahbclk() / div; -} - -unsigned long imx_get_gptclk(void) -{ - return imx_get_ipgclk(); -} - -unsigned long imx_get_fecclk(void) -{ - return imx_get_ipgclk(); -} - -static unsigned long imx_get_ipg_perclk(void) -{ - u32 reg; - - reg = ccm_readl(MX5_CCM_CBCDR); - if (!(reg & MX5_CCM_CBCDR_PERIPH_CLK_SEL)) - return pll2_sw_get_rate(); - reg = ccm_readl(MX5_CCM_CBCMR); - switch ((reg & MX5_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >> - MX5_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) { - case 0: - return pll1_main_get_rate(); - case 1: - return pll3_sw_get_rate(); - /* case 2: - TODO : LP_APM */ - } - return 0; -} - -unsigned long fsl_get_i2cclk(void) -{ - return imx_get_ipg_perclk(); -} - -unsigned long imx_get_mmcclk(void) -{ - u32 reg, prediv, podf, rate; - - reg = ccm_readl(MX5_CCM_CSCMR1); - reg &= MX5_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK; - reg >>= MX5_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET; - rate = get_rate_select(reg, - pll1_main_get_rate, - pll2_sw_get_rate, - pll3_sw_get_rate, - pll4_sw_get_rate); - - reg = ccm_readl(MX5_CCM_CSCDR1); - prediv = ((reg & MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK) >> - MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET) + 1; - podf = ((reg & MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK) >> - MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET) + 1; - - return rate / (prediv * podf); -} - -unsigned long imx_get_cspiclk(void) -{ - return 166000000; /* FIXME: bogus value */ -} - -void imx_dump_clocks(void) -{ - printf("pll1: %ld\n", pll1_main_get_rate()); - printf("pll2: %ld\n", pll2_sw_get_rate()); - printf("pll3: %ld\n", pll3_sw_get_rate()); - printf("pll4: %ld\n", pll4_sw_get_rate()); - printf("uart: %ld\n", imx_get_uartclk()); - printf("ipg: %ld\n", imx_get_ipgclk()); - printf("fec: %ld\n", imx_get_fecclk()); - printf("gpt: %ld\n", imx_get_gptclk()); - printf("i2c: %ld\n", fsl_get_i2cclk()); -} diff --git a/arch/arm/mach-imx/speed-imx6.c b/arch/arm/mach-imx/speed-imx6.c deleted file mode 100644 index 645b2c9735..0000000000 --- a/arch/arm/mach-imx/speed-imx6.c +++ /dev/null @@ -1,404 +0,0 @@ -#include -#include -#include -#include -#include -#include - -enum pll_clocks { - CPU_PLL1, /* System PLL */ - BUS_PLL2, /* System Bus PLL*/ - USBOTG_PLL3, /* OTG USB PLL */ - AUD_PLL4, /* Audio PLL */ - VID_PLL5, /* Video PLL */ - MLB_PLL6, /* MLB PLL */ - USBHOST_PLL7, /* Host USB PLL */ - ENET_PLL8, /* ENET PLL */ -}; - -#define SZ_DEC_1M 1000000 - -/* Out-of-reset PFDs and clock source definitions */ -#define PLL2_PFD0_FREQ 352000000 -#define PLL2_PFD1_FREQ 594000000 -#define PLL2_PFD2_FREQ 400000000 -#define PLL2_PFD2_DIV_FREQ 200000000 -#define PLL3_PFD0_FREQ 720000000 -#define PLL3_PFD1_FREQ 540000000 -#define PLL3_PFD2_FREQ 508200000 -#define PLL3_PFD3_FREQ 454700000 -#define PLL3_80M 80000000 -#define PLL3_60M 60000000 - -#define AHB_CLK_ROOT 132000000 -#define IPG_CLK_ROOT 66000000 -#define ENET_FREQ_0 25000000 -#define ENET_FREQ_1 50000000 -#define ENET_FREQ_2 100000000 -#define ENET_FREQ_3 125000000 - -#define CONFIG_MX6_HCLK_FREQ 24000000 - -static u32 __decode_pll(enum pll_clocks pll, u32 infreq) -{ - u32 div; - - switch (pll) { - case CPU_PLL1: - div = readl(MX6_ANATOP_BASE_ADDR + HW_ANADIG_PLL_SYS) & - BM_ANADIG_PLL_SYS_DIV_SELECT; - return infreq * (div >> 1); - case BUS_PLL2: - div = readl(MX6_ANATOP_BASE_ADDR + HW_ANADIG_PLL_528) & - BM_ANADIG_PLL_528_DIV_SELECT; - return infreq * (20 + (div << 1)); - case USBOTG_PLL3: - div = readl(MX6_ANATOP_BASE_ADDR + HW_ANADIG_USB2_PLL_480_CTRL) & - BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT; - return infreq * (20 + (div << 1)); - case ENET_PLL8: - div = readl(MX6_ANATOP_BASE_ADDR + HW_ANADIG_PLL_ENET) & - BM_ANADIG_PLL_ENET_DIV_SELECT; - switch (div) { - default: - case 0: - return ENET_FREQ_0; - case 1: - return ENET_FREQ_1; - case 2: - return ENET_FREQ_2; - case 3: - return ENET_FREQ_3; - } - case AUD_PLL4: - case VID_PLL5: - case MLB_PLL6: - case USBHOST_PLL7: - default: - return 0; - } -} - -static u32 __get_mcu_main_clk(void) -{ - u32 reg, freq; - reg = (__REG(MXC_CCM_CACRR) & MXC_CCM_CACRR_ARM_PODF_MASK) >> - MXC_CCM_CACRR_ARM_PODF_OFFSET; - freq = __decode_pll(CPU_PLL1, CONFIG_MX6_HCLK_FREQ); - return freq / (reg + 1); -} - -static u32 __get_periph_clk(void) -{ - u32 reg; - reg = __REG(MXC_CCM_CBCDR); - if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) { - reg = __REG(MXC_CCM_CBCMR); - switch ((reg & MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK) >> - MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET) { - case 0: - return __decode_pll(USBOTG_PLL3, CONFIG_MX6_HCLK_FREQ); - case 1: - case 2: - return CONFIG_MX6_HCLK_FREQ; - default: - return 0; - } - } else { - reg = __REG(MXC_CCM_CBCMR); - switch ((reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) >> - MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET) { - default: - case 0: - return __decode_pll(BUS_PLL2, CONFIG_MX6_HCLK_FREQ); - case 1: - return PLL2_PFD2_FREQ; - case 2: - return PLL2_PFD0_FREQ; - case 3: - return PLL2_PFD2_DIV_FREQ; - } - } -} - -static u32 __get_ipg_clk(void) -{ - u32 ahb_podf, ipg_podf; - - ahb_podf = __REG(MXC_CCM_CBCDR); - ipg_podf = (ahb_podf & MXC_CCM_CBCDR_IPG_PODF_MASK) >> - MXC_CCM_CBCDR_IPG_PODF_OFFSET; - ahb_podf = (ahb_podf & MXC_CCM_CBCDR_AHB_PODF_MASK) >> - MXC_CCM_CBCDR_AHB_PODF_OFFSET; - return __get_periph_clk() / ((ahb_podf + 1) * (ipg_podf + 1)); -} - -u32 imx_get_gptclk(void) -{ - return __get_ipg_clk(); -} - -static u32 __get_ipg_per_clk(void) -{ - u32 podf; - u32 clk_root = __get_ipg_clk(); - - podf = __REG(MXC_CCM_CSCMR1) & MXC_CCM_CSCMR1_PERCLK_PODF_MASK; - return clk_root / (podf + 1); -} - -u32 imx_get_uartclk(void) -{ - u32 freq = PLL3_80M, reg, podf; - - reg = __REG(MXC_CCM_CSCDR1); - podf = (reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >> - MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET; - freq /= (podf + 1); - - return freq; -} - -static u32 __get_cspi_clk(void) -{ - u32 freq = PLL3_60M, reg, podf; - - reg = __REG(MXC_CCM_CSCDR2); - podf = (reg & MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK) >> - MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET; - freq /= (podf + 1); - - return freq; -} - -static u32 __get_axi_clk(void) -{ - u32 clkroot; - u32 cbcdr = __REG(MXC_CCM_CBCDR); - u32 podf = (cbcdr & MXC_CCM_CBCDR_AXI_PODF_MASK) >> - MXC_CCM_CBCDR_AXI_PODF_OFFSET; - - if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) { - if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL) - clkroot = PLL2_PFD2_FREQ; - else - clkroot = PLL3_PFD1_FREQ;; - } else - clkroot = __get_periph_clk(); - - return clkroot / (podf + 1); -} - -static u32 __get_ahb_clk(void) -{ - u32 cbcdr = __REG(MXC_CCM_CBCDR); - u32 podf = (cbcdr & MXC_CCM_CBCDR_AHB_PODF_MASK) \ - >> MXC_CCM_CBCDR_AHB_PODF_OFFSET; - - return __get_periph_clk() / (podf + 1); -} - -static u32 __get_emi_slow_clk(void) -{ - u32 cscmr1 = __REG(MXC_CCM_CSCMR1); - u32 emi_clk_sel = (cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK) >> - MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET; - u32 podf = (cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK) >> - MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET; - - switch (emi_clk_sel) { - default: - case 0: - return __get_axi_clk() / (podf + 1); - case 1: - return __decode_pll(USBOTG_PLL3, CONFIG_MX6_HCLK_FREQ) / - (podf + 1); - case 2: - return PLL2_PFD2_FREQ / (podf + 1); - case 3: - return PLL2_PFD0_FREQ / (podf + 1); - } -} - -static u32 __get_nfc_clk(void) -{ - u32 clkroot; - u32 cs2cdr = __REG(MXC_CCM_CS2CDR); - u32 podf = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK) \ - >> MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET; - u32 pred = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK) \ - >> MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET; - - switch ((cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK) >> - MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET) { - default: - case 0: - clkroot = PLL2_PFD0_FREQ; - break; - case 1: - clkroot = __decode_pll(BUS_PLL2, CONFIG_MX6_HCLK_FREQ); - break; - case 2: - clkroot = __decode_pll(USBOTG_PLL3, CONFIG_MX6_HCLK_FREQ); - break; - case 3: - clkroot = PLL2_PFD2_FREQ; - break; - } - - return clkroot / (pred+1) / (podf+1); -} - -static u32 __get_ddr_clk(void) -{ - u32 cbcdr = __REG(MXC_CCM_CBCDR); - u32 podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK) >> - MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET; - - return __get_periph_clk() / (podf + 1); -} - -static u32 __get_usdhc1_clk(void) -{ - u32 clkroot; - u32 cscmr1 = __REG(MXC_CCM_CSCMR1); - u32 cscdr1 = __REG(MXC_CCM_CSCDR1); - u32 podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >> - MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET; - - if (cscmr1 & MXC_CCM_CSCMR1_USDHC1_CLK_SEL) - clkroot = PLL2_PFD0_FREQ; - else - clkroot = PLL2_PFD2_FREQ; - - return clkroot / (podf + 1); -} - -static u32 __get_usdhc2_clk(void) -{ - u32 clkroot; - u32 cscmr1 = __REG(MXC_CCM_CSCMR1); - u32 cscdr1 = __REG(MXC_CCM_CSCDR1); - u32 podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >> - MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET; - - if (cscmr1 & MXC_CCM_CSCMR1_USDHC2_CLK_SEL) - clkroot = PLL2_PFD0_FREQ; - else - clkroot = PLL2_PFD2_FREQ; - - return clkroot / (podf + 1); -} - -static u32 __get_usdhc3_clk(void) -{ - u32 clkroot; - u32 cscmr1 = __REG(MXC_CCM_CSCMR1); - u32 cscdr1 = __REG(MXC_CCM_CSCDR1); - u32 podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >> - MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET; - - if (cscmr1 & MXC_CCM_CSCMR1_USDHC3_CLK_SEL) - clkroot = PLL2_PFD0_FREQ; - else - clkroot = PLL2_PFD2_FREQ; - - return clkroot / (podf + 1); -} - -static u32 __get_usdhc4_clk(void) -{ - u32 clkroot; - u32 cscmr1 = __REG(MXC_CCM_CSCMR1); - u32 cscdr1 = __REG(MXC_CCM_CSCDR1); - u32 podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >> - MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET; - - if (cscmr1 & MXC_CCM_CSCMR1_USDHC4_CLK_SEL) - clkroot = PLL2_PFD0_FREQ; - else - clkroot = PLL2_PFD2_FREQ; - - return clkroot / (podf + 1); -} - -u32 imx_get_mmcclk(void) -{ - return __get_usdhc3_clk(); -} - -u32 imx_get_fecclk(void) -{ - return __get_ipg_clk(); -} - -u32 imx_get_i2cclk(void) -{ - return __get_ipg_per_clk(); -} - -u32 imx_get_cspiclk(void) -{ - return __get_cspi_clk(); -} - -void imx_dump_clocks(void) -{ - u32 freq; - - freq = __decode_pll(CPU_PLL1, CONFIG_MX6_HCLK_FREQ); - printf("mx6q pll1: %d\n", freq); - freq = __decode_pll(BUS_PLL2, CONFIG_MX6_HCLK_FREQ); - printf("mx6q pll2: %d\n", freq); - freq = __decode_pll(USBOTG_PLL3, CONFIG_MX6_HCLK_FREQ); - printf("mx6q pll3: %d\n", freq); - freq = __decode_pll(ENET_PLL8, CONFIG_MX6_HCLK_FREQ); - printf("mx6q pll8: %d\n", freq); - printf("mcu main: %d\n", __get_mcu_main_clk()); - printf("periph: %d\n", __get_periph_clk()); - printf("i2c: %d\n", __get_ipg_per_clk()); - printf("ipg: %d\n", __get_ipg_clk()); - printf("ipg per: %d\n", __get_ipg_per_clk()); - printf("cspi: %d\n", __get_cspi_clk()); - printf("axi: %d\n", __get_axi_clk()); - printf("ahb: %d\n", __get_ahb_clk()); - printf("emi slow: %d\n", __get_emi_slow_clk()); - printf("nfc: %d\n", __get_nfc_clk()); - printf("ddr: %d\n", __get_ddr_clk()); - printf("usdhc1: %d\n", __get_usdhc1_clk()); - printf("usdhc2: %d\n", __get_usdhc2_clk()); - printf("usdhc3: %d\n", __get_usdhc3_clk()); - printf("usdhc4: %d\n", __get_usdhc4_clk()); -} - -void imx6_ipu_clk_enable(int di) -{ - u32 reg; - - if (di == 1) { - reg = readl(MXC_CCM_CCGR3); - reg |= 0xC033; - writel(reg, MXC_CCM_CCGR3); - } else { - reg = readl(MXC_CCM_CCGR3); - reg |= 0x300F; - writel(reg, MXC_CCM_CCGR3); - } - - reg = readl(MX6_ANATOP_BASE_ADDR + 0xF0); - reg &= ~0x00003F00; - reg |= 0x00001300; - writel(reg, MX6_ANATOP_BASE_ADDR + 0xF4); - - reg = readl(MXC_CCM_CS2CDR); - reg &= ~0x00007E00; - reg |= 0x00001200; - writel(reg, MXC_CCM_CS2CDR); - - reg = readl(MXC_CCM_CSCMR2); - reg |= 0x00000C00; - writel(reg, MXC_CCM_CSCMR2); - - reg = 0x0002A953; - writel(reg, MXC_CCM_CHSCDR); -} diff --git a/arch/arm/mach-imx/speed.c b/arch/arm/mach-imx/speed.c deleted file mode 100644 index c86ad71758..0000000000 --- a/arch/arm/mach-imx/speed.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * (c) 2004 Sascha Hauer - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 -#include -#include -#include -#include - -/* - * get the system pll clock in Hz - * - * mfi + mfn / (mfd +1) - * f = 2 * f_ref * -------------------- - * pd + 1 - */ -unsigned int imx_decode_pll(unsigned int reg_val, unsigned int freq) -{ - unsigned long long ll; - int mfn_abs; - unsigned int mfi, mfn, mfd, pd; - - mfi = (reg_val >> 10) & 0xf; - mfn = reg_val & 0x3ff; - mfd = (reg_val >> 16) & 0x3ff; - pd = (reg_val >> 26) & 0xf; - - mfi = mfi <= 5 ? 5 : mfi; - - mfn_abs = mfn; - -#if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21 - if (mfn >= 0x200) { - mfn |= 0xFFFFFE00; - mfn_abs = -mfn; - } -#endif - - freq *= 2; - freq /= pd + 1; - - ll = (unsigned long long)freq * mfn_abs; - - do_div(ll, mfd + 1); - if (mfn < 0) - ll = -ll; - ll = (freq * mfi) + ll; - - return ll; -} - -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 - diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c index 449fe8dbca..7a13cdb0b2 100644 --- a/drivers/mci/imx-esdhc.c +++ b/drivers/mci/imx-esdhc.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c index 96f67122cc..354a1e3a01 100644 --- a/drivers/serial/serial_imx.c +++ b/drivers/serial/serial_imx.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c index 0229374f7a..568c304c86 100644 --- a/drivers/spi/imx_spi.c +++ b/drivers/spi/imx_spi.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/drivers/video/imx.c b/drivers/video/imx.c index 810d8e3ab6..7ddc2f1226 100644 --- a/drivers/video/imx.c +++ b/drivers/video/imx.c @@ -26,7 +26,6 @@ #include #include #include -#include #define LCDC_SSA 0x00 -- cgit v1.2.3