* [PATCH 01/11] clk: at91: rework main clk implementation
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
@ 2014-03-18 20:18 ` Boris BREZILLON
2014-03-18 20:18 ` [PATCH 02/11] clk: at91: update main clk documentation Boris BREZILLON
` (11 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-18 20:18 UTC (permalink / raw)
To: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot
Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel,
Boris BREZILLON, Boris BREZILLON
AT91 main clk a clk multiplexer and not a simple fixed rate clk as currently
implemented.
In some SoCs (sam9x5, sama5, sam9g45 families) this multiplexer can
choose among 2 sources: an internal RC oscillator circuit and an oscillator
using an external crystal.
In other Socs (sam9260, rm9200 families) the multiplexer source is
hardcoded to the external crystal oscillator.
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
drivers/clk/at91/clk-main.c | 581 ++++++++++++++++++++++++++++++++++++++-----
drivers/clk/at91/pmc.c | 12 +
drivers/clk/at91/pmc.h | 6 +
3 files changed, 536 insertions(+), 63 deletions(-)
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
index 8e9e8cc..4e8a26a 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -30,99 +30,550 @@
#define MAINF_LOOP_MIN_WAIT (USEC_PER_SEC / SLOW_CLOCK_FREQ)
#define MAINF_LOOP_MAX_WAIT MAINFRDY_TIMEOUT
-struct clk_main {
+#define MOR_KEY_MASK (0xff << 16)
+
+struct clk_main_osc {
struct clk_hw hw;
struct at91_pmc *pmc;
- unsigned long rate;
unsigned int irq;
wait_queue_head_t wait;
};
-#define to_clk_main(hw) container_of(hw, struct clk_main, hw)
+#define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
+
+struct clk_main_rc_osc {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ unsigned long frequency;
+ unsigned long accuracy;
+};
+
+#define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw)
+
+struct clk_rm9200_main {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+};
+
+#define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
-static irqreturn_t clk_main_irq_handler(int irq, void *dev_id)
+struct clk_sam9x5_main {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+ unsigned int irq;
+ wait_queue_head_t wait;
+ u8 parent;
+};
+
+#define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw)
+
+static irqreturn_t clk_main_osc_irq_handler(int irq, void *dev_id)
{
- struct clk_main *clkmain = (struct clk_main *)dev_id;
+ struct clk_main_osc *osc = dev_id;
- wake_up(&clkmain->wait);
- disable_irq_nosync(clkmain->irq);
+ wake_up(&osc->wait);
+ disable_irq_nosync(osc->irq);
return IRQ_HANDLED;
}
-static int clk_main_prepare(struct clk_hw *hw)
+static int clk_main_osc_prepare(struct clk_hw *hw)
{
- struct clk_main *clkmain = to_clk_main(hw);
- struct at91_pmc *pmc = clkmain->pmc;
- unsigned long halt_time, timeout;
+ struct clk_main_osc *osc = to_clk_main_osc(hw);
+ struct at91_pmc *pmc = osc->pmc;
u32 tmp;
+ tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK;
+ if (tmp & AT91_PMC_OSCBYPASS)
+ return 0;
+
+ if (!(tmp & AT91_PMC_MOSCEN)) {
+ tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
+ pmc_write(pmc, AT91_CKGR_MOR, tmp);
+ }
+
while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS)) {
- enable_irq(clkmain->irq);
- wait_event(clkmain->wait,
+ enable_irq(osc->irq);
+ wait_event(osc->wait,
pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS);
}
- if (clkmain->rate)
- return 0;
+ return 0;
+}
+
+static void clk_main_osc_unprepare(struct clk_hw *hw)
+{
+ struct clk_main_osc *osc = to_clk_main_osc(hw);
+ struct at91_pmc *pmc = osc->pmc;
+ u32 tmp = pmc_read(pmc, AT91_CKGR_MOR);
+
+ if (tmp & AT91_PMC_OSCBYPASS)
+ return;
+
+ if (!(tmp & AT91_PMC_MOSCEN))
+ return;
+
+ tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
+ pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
+}
+
+static int clk_main_osc_is_prepared(struct clk_hw *hw)
+{
+ struct clk_main_osc *osc = to_clk_main_osc(hw);
+ struct at91_pmc *pmc = osc->pmc;
+ u32 tmp = pmc_read(pmc, AT91_CKGR_MOR);
+
+ if (tmp & AT91_PMC_OSCBYPASS)
+ return 1;
+
+ return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS) &&
+ (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN));
+}
+
+static const struct clk_ops main_osc_ops = {
+ .prepare = clk_main_osc_prepare,
+ .unprepare = clk_main_osc_unprepare,
+ .is_prepared = clk_main_osc_is_prepared,
+};
+
+static struct clk * __init
+at91_clk_register_main_osc(struct at91_pmc *pmc,
+ unsigned int irq,
+ const char *name,
+ const char *parent_name,
+ bool bypass)
+{
+ int ret;
+ struct clk_main_osc *osc;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!pmc || !irq || !name || !parent_name)
+ return ERR_PTR(-EINVAL);
+
+ osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+ if (!osc)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &main_osc_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = 0;
+
+ osc->hw.init = &init;
+ osc->pmc = pmc;
+ osc->irq = irq;
+
+ init_waitqueue_head(&osc->wait);
+ irq_set_status_flags(osc->irq, IRQ_NOAUTOEN);
+ ret = request_irq(osc->irq, clk_main_osc_irq_handler,
+ IRQF_TRIGGER_HIGH, name, osc);
+ if (ret)
+ return ERR_PTR(ret);
+
+ if (bypass)
+ pmc_write(pmc, AT91_CKGR_MOR,
+ (pmc_read(pmc, AT91_CKGR_MOR) &
+ ~(MOR_KEY_MASK | AT91_PMC_MOSCEN)) |
+ AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
+
+ clk = clk_register(NULL, &osc->hw);
+ if (IS_ERR(clk)) {
+ free_irq(irq, osc);
+ kfree(osc);
+ }
+
+ return clk;
+}
+
+void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ struct clk *clk;
+ unsigned int irq;
+ const char *name = np->name;
+ const char *parent_name;
+ bool bypass;
+
+ of_property_read_string(np, "clock-output-names", &name);
+ bypass = of_property_read_bool(np, "atmel,osc-bypass");
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq)
+ return;
+
+ clk = at91_clk_register_main_osc(pmc, irq, name, parent_name, bypass);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static irqreturn_t clk_main_rc_osc_irq_handler(int irq, void *dev_id)
+{
+ struct clk_main_rc_osc *osc = dev_id;
+
+ wake_up(&osc->wait);
+ disable_irq_nosync(osc->irq);
+
+ return IRQ_HANDLED;
+}
+
+static int clk_main_rc_osc_prepare(struct clk_hw *hw)
+{
+ struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
+ struct at91_pmc *pmc = osc->pmc;
+ u32 tmp;
+
+ tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK;
+
+ if (!(tmp & AT91_PMC_MOSCRCEN)) {
+ tmp |= AT91_PMC_MOSCRCEN | AT91_PMC_KEY;
+ pmc_write(pmc, AT91_CKGR_MOR, tmp);
+ }
+
+ while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS)) {
+ enable_irq(osc->irq);
+ wait_event(osc->wait,
+ pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS);
+ }
+
+ return 0;
+}
+
+static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
+{
+ struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
+ struct at91_pmc *pmc = osc->pmc;
+ u32 tmp = pmc_read(pmc, AT91_CKGR_MOR);
+
+ if (!(tmp & AT91_PMC_MOSCRCEN))
+ return;
+
+ tmp &= ~(MOR_KEY_MASK | AT91_PMC_MOSCRCEN);
+ pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
+}
+
+static int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
+{
+ struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
+ struct at91_pmc *pmc = osc->pmc;
+
+ return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS) &&
+ (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCRCEN));
+}
+
+static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
+
+ return osc->frequency;
+}
+
+static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw,
+ unsigned long parent_acc)
+{
+ struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
+
+ return osc->accuracy;
+}
+
+static const struct clk_ops main_rc_osc_ops = {
+ .prepare = clk_main_rc_osc_prepare,
+ .unprepare = clk_main_rc_osc_unprepare,
+ .is_prepared = clk_main_rc_osc_is_prepared,
+ .recalc_rate = clk_main_rc_osc_recalc_rate,
+ .recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
+};
+
+static struct clk * __init
+at91_clk_register_main_rc_osc(struct at91_pmc *pmc,
+ unsigned int irq,
+ const char *name,
+ u32 frequency, u32 accuracy)
+{
+ int ret;
+ struct clk_main_rc_osc *osc;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!pmc || !irq || !name || !frequency)
+ return ERR_PTR(-EINVAL);
+
+ osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+ if (!osc)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &main_osc_ops;
+ init.parent_names = NULL;
+ init.num_parents = 0;
+ /*
+ * Internal RC oscillator must be enabled on reset, so
+ * keep it enabled even if unused.
+ */
+ init.flags = CLK_IGNORE_UNUSED;
+
+ osc->hw.init = &init;
+ osc->pmc = pmc;
+ osc->irq = irq;
+ osc->frequency = frequency;
+ osc->accuracy = accuracy;
+
+ init_waitqueue_head(&osc->wait);
+ irq_set_status_flags(osc->irq, IRQ_NOAUTOEN);
+ ret = request_irq(osc->irq, clk_main_rc_osc_irq_handler,
+ IRQF_TRIGGER_HIGH, name, osc);
+ if (ret)
+ return ERR_PTR(ret);
+
+ clk = clk_register(NULL, &osc->hw);
+ if (IS_ERR(clk)) {
+ free_irq(irq, osc);
+ kfree(osc);
+ }
+
+ return clk;
+}
+
+void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ struct clk *clk;
+ unsigned int irq;
+ u32 frequency = 0;
+ u32 accuracy = 0;
+ const char *name = np->name;
+
+ of_property_read_string(np, "clock-output-names", &name);
+ of_property_read_u32(np, "clock-frequency", &frequency);
+ of_property_read_u32(np, "clock-accuracy", &accuracy);
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq)
+ return;
+
+ clk = at91_clk_register_main_rc_osc(pmc, irq, name, frequency,
+ accuracy);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+
+static int clk_main_probe_frequency(struct at91_pmc *pmc)
+{
+ unsigned long prep_time, timeout;
+ u32 tmp;
timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
do {
- halt_time = jiffies;
+ prep_time = jiffies;
tmp = pmc_read(pmc, AT91_CKGR_MCFR);
if (tmp & AT91_PMC_MAINRDY)
return 0;
usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
- } while (time_before(halt_time, timeout));
+ } while (time_before(prep_time, timeout));
- return 0;
+ return -ETIMEDOUT;
}
-static int clk_main_is_prepared(struct clk_hw *hw)
+static unsigned long clk_main_recalc_rate(struct at91_pmc *pmc,
+ unsigned long parent_rate)
{
- struct clk_main *clkmain = to_clk_main(hw);
+ u32 tmp;
+
+ if (parent_rate)
+ return parent_rate;
+
+ tmp = pmc_read(pmc, AT91_CKGR_MCFR);
+ if (!(tmp & AT91_PMC_MAINRDY))
+ return 0;
- return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCS);
+ return ((tmp & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
}
-static unsigned long clk_main_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
+static int clk_rm9200_main_prepare(struct clk_hw *hw)
{
- u32 tmp;
- struct clk_main *clkmain = to_clk_main(hw);
+ struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
+
+ return clk_main_probe_frequency(clkmain->pmc);
+}
+
+static int clk_rm9200_main_is_prepared(struct clk_hw *hw)
+{
+ struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
+
+ return !!(pmc_read(clkmain->pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINRDY);
+}
+
+static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
+
+ return clk_main_recalc_rate(clkmain->pmc, parent_rate);
+}
+
+static const struct clk_ops rm9200_main_ops = {
+ .prepare = clk_rm9200_main_prepare,
+ .is_prepared = clk_rm9200_main_is_prepared,
+ .recalc_rate = clk_rm9200_main_recalc_rate,
+};
+
+static struct clk * __init
+at91_clk_register_rm9200_main(struct at91_pmc *pmc,
+ const char *name,
+ const char *parent_name)
+{
+ struct clk_rm9200_main *clkmain;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!pmc || !name)
+ return ERR_PTR(-EINVAL);
+
+ if (!parent_name)
+ return ERR_PTR(-EINVAL);
+
+ clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
+ if (!clkmain)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &rm9200_main_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = 0;
+
+ clkmain->hw.init = &init;
+ clkmain->pmc = pmc;
+
+ clk = clk_register(NULL, &clkmain->hw);
+ if (IS_ERR(clk))
+ kfree(clkmain);
+
+ return clk;
+}
+
+void __init of_at91rm9200_clk_main_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ of_property_read_string(np, "clock-output-names", &name);
+
+ clk = at91_clk_register_rm9200_main(pmc, name, parent_name);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static irqreturn_t clk_sam9x5_main_irq_handler(int irq, void *dev_id)
+{
+ struct clk_sam9x5_main *clkmain = dev_id;
+
+ wake_up(&clkmain->wait);
+ disable_irq_nosync(clkmain->irq);
+
+ return IRQ_HANDLED;
+}
+
+static int clk_sam9x5_main_prepare(struct clk_hw *hw)
+{
+ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
struct at91_pmc *pmc = clkmain->pmc;
- if (clkmain->rate)
- return clkmain->rate;
+ while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) {
+ enable_irq(clkmain->irq);
+ wait_event(clkmain->wait,
+ pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS);
+ }
+
+ return clk_main_probe_frequency(pmc);
+}
- tmp = pmc_read(pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINF;
- clkmain->rate = (tmp * parent_rate) / MAINF_DIV;
+static int clk_sam9x5_main_is_prepared(struct clk_hw *hw)
+{
+ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
- return clkmain->rate;
+ return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS);
}
-static const struct clk_ops main_ops = {
- .prepare = clk_main_prepare,
- .is_prepared = clk_main_is_prepared,
- .recalc_rate = clk_main_recalc_rate,
+static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
+
+ return clk_main_recalc_rate(clkmain->pmc, parent_rate);
+}
+
+static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
+ struct at91_pmc *pmc = clkmain->pmc;
+ u32 tmp;
+
+ if (index > 1)
+ return -EINVAL;
+
+ tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK;
+
+ if (index && !(tmp & AT91_PMC_MOSCSEL))
+ pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
+ else if (!index && (tmp & AT91_PMC_MOSCSEL))
+ pmc_write(pmc, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
+
+ while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) {
+ enable_irq(clkmain->irq);
+ wait_event(clkmain->wait,
+ pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS);
+ }
+
+ return 0;
+}
+
+static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)
+{
+ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
+
+ return !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN);
+}
+
+static const struct clk_ops sam9x5_main_ops = {
+ .prepare = clk_sam9x5_main_prepare,
+ .is_prepared = clk_sam9x5_main_is_prepared,
+ .recalc_rate = clk_sam9x5_main_recalc_rate,
+ .set_parent = clk_sam9x5_main_set_parent,
+ .get_parent = clk_sam9x5_main_get_parent,
};
static struct clk * __init
-at91_clk_register_main(struct at91_pmc *pmc,
- unsigned int irq,
- const char *name,
- const char *parent_name,
- unsigned long rate)
+at91_clk_register_sam9x5_main(struct at91_pmc *pmc,
+ unsigned int irq,
+ const char *name,
+ const char **parent_names,
+ int num_parents)
{
int ret;
- struct clk_main *clkmain;
+ struct clk_sam9x5_main *clkmain;
struct clk *clk = NULL;
struct clk_init_data init;
if (!pmc || !irq || !name)
return ERR_PTR(-EINVAL);
- if (!rate && !parent_name)
+ if (!parent_names || !num_parents)
return ERR_PTR(-EINVAL);
clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
@@ -130,19 +581,20 @@ at91_clk_register_main(struct at91_pmc *pmc,
return ERR_PTR(-ENOMEM);
init.name = name;
- init.ops = &main_ops;
- init.parent_names = parent_name ? &parent_name : NULL;
- init.num_parents = parent_name ? 1 : 0;
- init.flags = parent_name ? 0 : CLK_IS_ROOT;
+ init.ops = &sam9x5_main_ops;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+ init.flags = CLK_SET_PARENT_GATE;
clkmain->hw.init = &init;
- clkmain->rate = rate;
clkmain->pmc = pmc;
clkmain->irq = irq;
+ clkmain->parent = !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) &
+ AT91_PMC_MOSCEN);
init_waitqueue_head(&clkmain->wait);
irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN);
- ret = request_irq(clkmain->irq, clk_main_irq_handler,
- IRQF_TRIGGER_HIGH, "clk-main", clkmain);
+ ret = request_irq(clkmain->irq, clk_sam9x5_main_irq_handler,
+ IRQF_TRIGGER_HIGH, name, clkmain);
if (ret)
return ERR_PTR(ret);
@@ -155,33 +607,36 @@ at91_clk_register_main(struct at91_pmc *pmc,
return clk;
}
-
-
-static void __init
-of_at91_clk_main_setup(struct device_node *np, struct at91_pmc *pmc)
+void __init of_at91sam9x5_clk_main_setup(struct device_node *np,
+ struct at91_pmc *pmc)
{
struct clk *clk;
+ const char *parent_names[2];
+ int num_parents;
unsigned int irq;
- const char *parent_name;
const char *name = np->name;
- u32 rate = 0;
+ int i;
+
+ num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+ if (num_parents <= 0 || num_parents > 2)
+ return;
+
+ for (i = 0; i < num_parents; ++i) {
+ parent_names[i] = of_clk_get_parent_name(np, i);
+ if (!parent_names[i])
+ return;
+ }
- parent_name = of_clk_get_parent_name(np, 0);
of_property_read_string(np, "clock-output-names", &name);
- of_property_read_u32(np, "clock-frequency", &rate);
+
irq = irq_of_parse_and_map(np, 0);
if (!irq)
return;
- clk = at91_clk_register_main(pmc, irq, name, parent_name, rate);
+ clk = at91_clk_register_sam9x5_main(pmc, irq, name, parent_names,
+ num_parents);
if (IS_ERR(clk))
return;
of_clk_add_provider(np, of_clk_src_simple_get, clk);
}
-
-void __init of_at91rm9200_clk_main_setup(struct device_node *np,
- struct at91_pmc *pmc)
-{
- of_at91_clk_main_setup(np, pmc);
-}
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 6a61477..dc5fdde 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -231,9 +231,21 @@ out_free_pmc:
static const struct of_device_id pmc_clk_ids[] __initconst = {
/* Main clock */
{
+ .compatible = "atmel,at91rm9200-clk-main-osc",
+ .data = of_at91rm9200_clk_main_osc_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9x5-clk-main-rc-osc",
+ .data = of_at91sam9x5_clk_main_rc_osc_setup,
+ },
+ {
.compatible = "atmel,at91rm9200-clk-main",
.data = of_at91rm9200_clk_main_setup,
},
+ {
+ .compatible = "atmel,at91sam9x5-clk-main",
+ .data = of_at91sam9x5_clk_main_setup,
+ },
/* PLL clocks */
{
.compatible = "atmel,at91rm9200-clk-pll",
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 4413509..42cc7cc 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -58,8 +58,14 @@ static inline void pmc_write(struct at91_pmc *pmc, int offset, u32 value)
int of_at91_get_clk_range(struct device_node *np, const char *propname,
struct clk_range *range);
+extern void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+extern void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np,
+ struct at91_pmc *pmc);
extern void __init of_at91rm9200_clk_main_setup(struct device_node *np,
struct at91_pmc *pmc);
+extern void __init of_at91sam9x5_clk_main_setup(struct device_node *np,
+ struct at91_pmc *pmc);
extern void __init of_at91rm9200_clk_pll_setup(struct device_node *np,
struct at91_pmc *pmc);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 02/11] clk: at91: update main clk documentation
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
2014-03-18 20:18 ` [PATCH 01/11] clk: at91: rework main " Boris BREZILLON
@ 2014-03-18 20:18 ` Boris BREZILLON
2014-03-18 20:18 ` [PATCH 03/11] clk: at91: add slow clks driver Boris BREZILLON
` (10 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-18 20:18 UTC (permalink / raw)
To: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot
Cc: devicetree, Boris BREZILLON, linux-kernel, linux-arm-kernel,
linux-doc
Update main clk documentation to match main clk implementation rework.
Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
---
.../devicetree/bindings/clock/at91-clock.txt | 56 ++++++++++++++++----
1 file changed, 47 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt
index cd5e239..9a7025b 100644
--- a/Documentation/devicetree/bindings/clock/at91-clock.txt
+++ b/Documentation/devicetree/bindings/clock/at91-clock.txt
@@ -15,8 +15,13 @@ Required properties:
All at91 specific clocks (clocks defined below) must be child
node of the PMC node.
+ "atmel,at91rm9200-clk-main-osc"
+ "atmel,at91sam9x5-clk-main-rc-osc"
+ at91 main clk sources
+
+ "atmel,at91sam9x5-clk-main"
"atmel,at91rm9200-clk-main":
- at91 main oscillator
+ at91 main clock
"atmel,at91rm9200-clk-master" or
"atmel,at91sam9x5-clk-master":
@@ -85,24 +90,57 @@ For example:
/* put at91 clocks here */
};
+Required properties for main clock oscillator:
+- interrupt-parent : must reference the PMC node.
+- interrupts : shall be set to "<0>".
+- clock-frequency : define the internal RC oscillator frequency.
+
+Optional properties:
+- clock-accuracy : define the internal RC oscillator accuracy.
+
+For example:
+ main_rc_osc: main_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-main-rc-osc";
+ interrupt-parent = <&pmc>;
+ interrupts = <0>;
+ clock-frequency = <12000000>;
+ clock-accuracy = <50000000>;
+ };
+
+Required properties for main clock internal RC oscillator:
+- interrupt-parent : must reference the PMC node.
+- interrupts : shall be set to "<0>".
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks : shall encode the main osc source clk sources (see atmel datasheet).
+
+Optional properties:
+- atmel,osc-bypass : boolean property. Specified if a clock signal is provided
+ on XIN.
+
+ clock signal is directly provided on XIN pin.
+
+For example:
+ main_osc: main_osc {
+ compatible = "atmel,at91rm9200-clk-main-osc";
+ interrupt-parent = <&pmc>;
+ interrupts = <0>;
+ #clock-cells = <0>;
+ clocks = <&main_xtal>;
+ };
+
Required properties for main clock:
- interrupt-parent : must reference the PMC node.
- interrupts : shall be set to "<0>".
- #clock-cells : from common clock binding; shall be set to 0.
-- clocks (optional if clock-frequency is provided) : shall be the slow clock
- phandle. This clock is used to calculate the main clock rate if
- "clock-frequency" is not provided.
-- clock-frequency : the main oscillator frequency.Prefer the use of
- "clock-frequency" over automatic clock rate calculation.
+- clocks : shall encode the main clk sources (see atmel datasheet).
For example:
main: mainck {
- compatible = "atmel,at91rm9200-clk-main";
+ compatible = "atmel,at91sam9x5-clk-main";
interrupt-parent = <&pmc>;
interrupts = <0>;
#clock-cells = <0>;
- clocks = <&ck32k>;
- clock-frequency = <18432000>;
+ clocks = <&main_rc_osc &main_osc>;
};
Required properties for master clock:
--
1.7.9.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 03/11] clk: at91: add slow clks driver
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
2014-03-18 20:18 ` [PATCH 01/11] clk: at91: rework main " Boris BREZILLON
2014-03-18 20:18 ` [PATCH 02/11] clk: at91: update main clk documentation Boris BREZILLON
@ 2014-03-18 20:18 ` Boris BREZILLON
2014-03-18 20:18 ` [PATCH 04/11] clk: at91: add slow clk documentation Boris BREZILLON
` (9 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-18 20:18 UTC (permalink / raw)
To: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot
Cc: devicetree, Boris BREZILLON, linux-doc, linux-kernel,
Boris BREZILLON, linux-arm-kernel
AT91 slow clk is a clk multiplexer.
In some SoCs (sam9x5, sama5, sam9g45 families) this multiplexer can
choose among 2 sources: an internal RC oscillator circuit and an oscillator
using an external crystal.
In other Socs (sam9260 family) the multiplexer source is hardcoded with
the OSCSEL signal.
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
drivers/clk/at91/Makefile | 4 +-
drivers/clk/at91/clk-slow.c | 467 ++++++++++++++++++++++++++++++++++++++++++
drivers/clk/at91/pmc.h | 3 +
drivers/clk/at91/sckc.c | 57 ++++++
drivers/clk/at91/sckc.h | 22 ++
include/linux/clk/at91_pmc.h | 1 +
6 files changed, 552 insertions(+), 2 deletions(-)
create mode 100644 drivers/clk/at91/clk-slow.c
create mode 100644 drivers/clk/at91/sckc.c
create mode 100644 drivers/clk/at91/sckc.h
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 46c1d3d..4998aee 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -2,8 +2,8 @@
# Makefile for at91 specific clk
#
-obj-y += pmc.o
-obj-y += clk-main.o clk-pll.o clk-plldiv.o clk-master.o
+obj-y += pmc.o sckc.o
+obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o
obj-y += clk-system.o clk-peripheral.o clk-programmable.o
obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o
diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c
new file mode 100644
index 0000000..fc2d54c
--- /dev/null
+++ b/drivers/clk/at91/clk-slow.c
@@ -0,0 +1,467 @@
+/*
+ * drivers/clk/at91/clk-slow.c
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+
+#include "pmc.h"
+#include "sckc.h"
+
+#define SLOW_CLOCK_FREQ 32768
+#define SLOWCK_SW_CYCLES 5
+#define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
+ SLOW_CLOCK_FREQ)
+
+#define AT91_SCKC_CR 0x00
+#define AT91_SCKC_RCEN (1 << 0)
+#define AT91_SCKC_OSC32EN (1 << 1)
+#define AT91_SCKC_OSC32BYP (1 << 2)
+#define AT91_SCKC_OSCSEL (1 << 3)
+
+struct clk_slow_osc {
+ struct clk_hw hw;
+ void __iomem *sckcr;
+ unsigned long startup_usec;
+};
+
+#define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)
+
+struct clk_slow_rc_osc {
+ struct clk_hw hw;
+ void __iomem *sckcr;
+ unsigned long frequency;
+ unsigned long accuracy;
+ unsigned long startup_usec;
+};
+
+#define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)
+
+struct clk_sam9260_slow {
+ struct clk_hw hw;
+ struct at91_pmc *pmc;
+};
+
+#define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw)
+
+struct clk_sam9x5_slow {
+ struct clk_hw hw;
+ void __iomem *sckcr;
+ u8 parent;
+};
+
+#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
+
+
+static int clk_slow_osc_prepare(struct clk_hw *hw)
+{
+ struct clk_slow_osc *osc = to_clk_slow_osc(hw);
+ void __iomem *sckcr = osc->sckcr;
+ u32 tmp = readl(sckcr);
+
+ if (tmp & AT91_SCKC_OSC32BYP)
+ return 0;
+
+ writel(tmp | AT91_SCKC_OSC32EN, sckcr);
+
+ usleep_range(osc->startup_usec, osc->startup_usec + 1);
+
+ return 0;
+}
+
+static void clk_slow_osc_unprepare(struct clk_hw *hw)
+{
+ struct clk_slow_osc *osc = to_clk_slow_osc(hw);
+ void __iomem *sckcr = osc->sckcr;
+ u32 tmp = readl(sckcr);
+
+ if (tmp & AT91_SCKC_OSC32BYP)
+ return;
+
+ writel(tmp & ~AT91_SCKC_OSC32EN, sckcr);
+}
+
+static int clk_slow_osc_is_prepared(struct clk_hw *hw)
+{
+ struct clk_slow_osc *osc = to_clk_slow_osc(hw);
+ void __iomem *sckcr = osc->sckcr;
+ u32 tmp = readl(sckcr);
+
+ if (tmp & AT91_SCKC_OSC32BYP)
+ return 1;
+
+ return !!(tmp & AT91_SCKC_OSC32EN);
+}
+
+static const struct clk_ops slow_osc_ops = {
+ .prepare = clk_slow_osc_prepare,
+ .unprepare = clk_slow_osc_unprepare,
+ .is_prepared = clk_slow_osc_is_prepared,
+};
+
+static struct clk * __init
+at91_clk_register_slow_osc(void __iomem *sckcr,
+ const char *name,
+ const char *parent_name,
+ unsigned long startup,
+ bool bypass)
+{
+ struct clk_slow_osc *osc;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!sckcr || !name || !parent_name)
+ return ERR_PTR(-EINVAL);
+
+ osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+ if (!osc)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &slow_osc_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = 0;
+
+ osc->hw.init = &init;
+ osc->sckcr = sckcr;
+ osc->startup_usec = startup;
+
+ if (bypass)
+ writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP,
+ sckcr);
+
+ clk = clk_register(NULL, &osc->hw);
+ if (IS_ERR(clk))
+ kfree(osc);
+
+ return clk;
+}
+
+void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np,
+ void __iomem *sckcr)
+{
+ struct clk *clk;
+ const char *parent_name;
+ const char *name = np->name;
+ u32 startup;
+ bool bypass;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ of_property_read_string(np, "clock-output-names", &name);
+ of_property_read_u32(np, "atmel,startup-time-usec", &startup);
+ bypass = of_property_read_bool(np, "atmel,osc-bypass");
+
+ clk = at91_clk_register_slow_osc(sckcr, name, parent_name, startup,
+ bypass);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
+
+ return osc->frequency;
+}
+
+static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw,
+ unsigned long parent_acc)
+{
+ struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
+
+ return osc->accuracy;
+}
+
+static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
+{
+ struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
+ void __iomem *sckcr = osc->sckcr;
+
+ writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr);
+
+ usleep_range(osc->startup_usec, osc->startup_usec + 1);
+
+ return 0;
+}
+
+static void clk_slow_rc_osc_unprepare(struct clk_hw *hw)
+{
+ struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
+ void __iomem *sckcr = osc->sckcr;
+
+ writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr);
+}
+
+static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw)
+{
+ struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
+
+ return !!(readl(osc->sckcr) & AT91_SCKC_RCEN);
+}
+
+static const struct clk_ops slow_rc_osc_ops = {
+ .prepare = clk_slow_rc_osc_prepare,
+ .unprepare = clk_slow_rc_osc_unprepare,
+ .is_prepared = clk_slow_rc_osc_is_prepared,
+ .recalc_rate = clk_slow_rc_osc_recalc_rate,
+ .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy,
+};
+
+static struct clk * __init
+at91_clk_register_slow_rc_osc(void __iomem *sckcr,
+ const char *name,
+ unsigned long frequency,
+ unsigned long accuracy,
+ unsigned long startup)
+{
+ struct clk_slow_rc_osc *osc;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!sckcr || !name)
+ return ERR_PTR(-EINVAL);
+
+ osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+ if (!osc)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &slow_rc_osc_ops;
+ init.parent_names = NULL;
+ init.num_parents = 0;
+ init.flags = CLK_IS_ROOT;
+
+ osc->hw.init = &init;
+ osc->sckcr = sckcr;
+ osc->frequency = frequency;
+ osc->accuracy = accuracy;
+ osc->startup_usec = startup;
+
+ clk = clk_register(NULL, &osc->hw);
+ if (IS_ERR(clk))
+ kfree(osc);
+
+ return clk;
+}
+
+void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np,
+ void __iomem *sckcr)
+{
+ struct clk *clk;
+ u32 frequency = 0;
+ u32 accuracy = 0;
+ u32 startup = 0;
+ const char *name = np->name;
+
+ of_property_read_string(np, "clock-output-names", &name);
+ of_property_read_u32(np, "clock-frequency", &frequency);
+ of_property_read_u32(np, "clock-accuracy", &accuracy);
+ of_property_read_u32(np, "atmel,startup-time-usec", &startup);
+
+ clk = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy,
+ startup);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
+ void __iomem *sckcr = slowck->sckcr;
+ u32 tmp;
+
+ if (index > 1)
+ return -EINVAL;
+
+ tmp = readl(sckcr);
+
+ if ((!index && !(tmp & AT91_SCKC_OSCSEL)) ||
+ (index && (tmp & AT91_SCKC_OSCSEL)))
+ return 0;
+
+ if (index)
+ tmp |= AT91_SCKC_OSCSEL;
+ else
+ tmp &= ~AT91_SCKC_OSCSEL;
+
+ writel(tmp, sckcr);
+
+ usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
+
+ return 0;
+}
+
+static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw)
+{
+ struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
+
+ return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL);
+}
+
+static const struct clk_ops sam9x5_slow_ops = {
+ .set_parent = clk_sam9x5_slow_set_parent,
+ .get_parent = clk_sam9x5_slow_get_parent,
+};
+
+static struct clk * __init
+at91_clk_register_sam9x5_slow(void __iomem *sckcr,
+ const char *name,
+ const char **parent_names,
+ int num_parents)
+{
+ struct clk_sam9x5_slow *slowck;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!sckcr || !name || !parent_names || !num_parents)
+ return ERR_PTR(-EINVAL);
+
+ slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
+ if (!slowck)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &sam9x5_slow_ops;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+ init.flags = 0;
+
+ slowck->hw.init = &init;
+ slowck->sckcr = sckcr;
+ slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL);
+
+ clk = clk_register(NULL, &slowck->hw);
+ if (IS_ERR(clk))
+ kfree(slowck);
+
+ return clk;
+}
+
+void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
+ void __iomem *sckcr)
+{
+ struct clk *clk;
+ const char *parent_names[2];
+ int num_parents;
+ const char *name = np->name;
+ int i;
+
+ num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+ if (num_parents <= 0 || num_parents > 2)
+ return;
+
+ for (i = 0; i < num_parents; ++i) {
+ parent_names[i] = of_clk_get_parent_name(np, i);
+ if (!parent_names[i])
+ return;
+ }
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ clk = at91_clk_register_sam9x5_slow(sckcr, name, parent_names,
+ num_parents);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw)
+{
+ struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw);
+
+ return !!(pmc_read(slowck->pmc, AT91_PMC_SR) & AT91_PMC_OSCSEL);
+}
+
+static const struct clk_ops sam9260_slow_ops = {
+ .get_parent = clk_sam9260_slow_get_parent,
+};
+
+static struct clk * __init
+at91_clk_register_sam9260_slow(struct at91_pmc *pmc,
+ const char *name,
+ const char **parent_names,
+ int num_parents)
+{
+ struct clk_sam9260_slow *slowck;
+ struct clk *clk = NULL;
+ struct clk_init_data init;
+
+ if (!pmc || !name)
+ return ERR_PTR(-EINVAL);
+
+ if (!parent_names || !num_parents)
+ return ERR_PTR(-EINVAL);
+
+ slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
+ if (!slowck)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &sam9260_slow_ops;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+ init.flags = 0;
+
+ slowck->hw.init = &init;
+ slowck->pmc = pmc;
+
+ clk = clk_register(NULL, &slowck->hw);
+ if (IS_ERR(clk))
+ kfree(slowck);
+
+ return clk;
+}
+
+void __init of_at91sam9260_clk_slow_setup(struct device_node *np,
+ struct at91_pmc *pmc)
+{
+ struct clk *clk;
+ const char *parent_names[2];
+ int num_parents;
+ const char *name = np->name;
+ int i;
+
+ num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+ if (num_parents <= 0 || num_parents > 1)
+ return;
+
+ for (i = 0; i < num_parents; ++i) {
+ parent_names[i] = of_clk_get_parent_name(np, i);
+ if (!parent_names[i])
+ return;
+ }
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ clk = at91_clk_register_sam9260_slow(pmc, name, parent_names,
+ num_parents);
+ if (IS_ERR(clk))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 42cc7cc..6c76259 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -58,6 +58,9 @@ static inline void pmc_write(struct at91_pmc *pmc, int offset, u32 value)
int of_at91_get_clk_range(struct device_node *np, const char *propname,
struct clk_range *range);
+extern void __init of_at91sam9260_clk_slow_setup(struct device_node *np,
+ struct at91_pmc *pmc);
+
extern void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np,
struct at91_pmc *pmc);
extern void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np,
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
new file mode 100644
index 0000000..1184d76
--- /dev/null
+++ b/drivers/clk/at91/sckc.c
@@ -0,0 +1,57 @@
+/*
+ * drivers/clk/at91/sckc.c
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+
+#include "sckc.h"
+
+static const struct of_device_id sckc_clk_ids[] __initconst = {
+ /* Slow clock */
+ {
+ .compatible = "atmel,at91sam9x5-clk-slow-osc",
+ .data = of_at91sam9x5_clk_slow_osc_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9x5-clk-slow-rc-osc",
+ .data = of_at91sam9x5_clk_slow_rc_osc_setup,
+ },
+ {
+ .compatible = "atmel,at91sam9x5-clk-slow",
+ .data = of_at91sam9x5_clk_slow_setup,
+ },
+ { /*sentinel*/ }
+};
+
+static void __init of_at91sam9x5_sckc_setup(struct device_node *np)
+{
+ struct device_node *childnp;
+ void (*clk_setup)(struct device_node *, void __iomem *);
+ const struct of_device_id *clk_id;
+ void __iomem *regbase = of_iomap(np, 0);
+
+ if (!regbase)
+ return;
+
+ for_each_child_of_node(np, childnp) {
+ clk_id = of_match_node(sckc_clk_ids, childnp);
+ if (!clk_id)
+ continue;
+ clk_setup = clk_id->data;
+ clk_setup(childnp, regbase);
+ }
+}
+CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc",
+ of_at91sam9x5_sckc_setup);
diff --git a/drivers/clk/at91/sckc.h b/drivers/clk/at91/sckc.h
new file mode 100644
index 0000000..836fcf5
--- /dev/null
+++ b/drivers/clk/at91/sckc.h
@@ -0,0 +1,22 @@
+/*
+ * drivers/clk/at91/sckc.h
+ *
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * 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.
+ */
+
+#ifndef __AT91_SCKC_H_
+#define __AT91_SCKC_H_
+
+extern void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np,
+ void __iomem *sckcr);
+extern void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np,
+ void __iomem *sckcr);
+extern void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
+ void __iomem *sckcr);
+
+#endif /* __AT91_SCKC_H_ */
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index a6911eb..de4268d 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -155,6 +155,7 @@ extern void __iomem *at91_pmc_base;
#define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */
#define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */
#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [some SAM9] */
+#define AT91_PMC_OSCSEL (1 << 7) /* Slow Oscillator Selection [some SAM9] */
#define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */
#define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */
#define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 04/11] clk: at91: add slow clk documentation
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
` (2 preceding siblings ...)
2014-03-18 20:18 ` [PATCH 03/11] clk: at91: add slow clks driver Boris BREZILLON
@ 2014-03-18 20:18 ` Boris BREZILLON
2014-03-18 20:18 ` [PATCH 05/11] ARM: at91/dt: move sama5d3 SoC to the new main/slow clk model Boris BREZILLON
` (8 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-18 20:18 UTC (permalink / raw)
To: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot
Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel,
Boris BREZILLON
Add slow clk, and slow oscillators documentation.
Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
---
.../devicetree/bindings/clock/at91-clock.txt | 72 ++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt
index 9a7025b..820061c 100644
--- a/Documentation/devicetree/bindings/clock/at91-clock.txt
+++ b/Documentation/devicetree/bindings/clock/at91-clock.txt
@@ -6,6 +6,16 @@ This binding uses the common clock binding[1].
Required properties:
- compatible : shall be one of the following:
+ "atmel,at91sam9x5-sckc":
+ at91 SCKC (Slow Clock Controller)
+ This node contains the slow clock definitions.
+
+ "atmel,at91sam9x5-clk-slow-osc":
+ at91 slow oscillator
+
+ "atmel,at91sam9x5-clk-slow-rc-osc":
+ at91 internal slow RC oscillator
+
"atmel,at91rm9200-pmc" or
"atmel,at91sam9g45-pmc" or
"atmel,at91sam9n12-pmc" or
@@ -15,6 +25,11 @@ Required properties:
All at91 specific clocks (clocks defined below) must be child
node of the PMC node.
+ "atmel,at91sam9x5-clk-slow" (under sckc node)
+ or
+ "atmel,at91sam9260-clk-slow" (under pmc node):
+ at91 slow clk
+
"atmel,at91rm9200-clk-main-osc"
"atmel,at91sam9x5-clk-main-rc-osc"
at91 main clk sources
@@ -59,6 +74,63 @@ Required properties:
"atmel,at91sam9x5-clk-utmi":
at91 utmi clock
+Required properties for SCKC node:
+- reg : defines the IO memory reserved for the SCKC.
+- #size-cells : shall be 0 (reg is used to encode clk id).
+- #address-cells : shall be 1 (reg is used to encode clk id).
+
+
+For example:
+ ckc: sckc@fffffe50 {
+ compatible = "atmel,sama5d3-pmc";
+ reg = <0xfffffe50 0x4>
+ #size-cells = <0>;
+ #address-cells = <1>;
+
+ /* put at91 slow clocks here */
+ };
+
+
+Required properties for internal slow RC oscillator:
+- #clock-cells : from common clock binding; shall be set to 0.
+- clock-frequency : define the internal RC oscillator frequency.
+
+Optional properties:
+- clock-accuracy : define the internal RC oscillator accuracy.
+
+For example:
+ slow_rc_osc: slow_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
+ clock-frequency = <32768>;
+ clock-accuracy = <50000000>;
+ };
+
+Required properties for slow oscillator:
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks : shall encode the main osc source clk sources (see atmel datasheet).
+
+Optional properties:
+- atmel,osc-bypass : boolean property. Set this when a clock signal is directly
+ provided on XIN.
+
+For example:
+ slow_osc: slow_osc {
+ compatible = "atmel,at91rm9200-clk-slow-osc";
+ #clock-cells = <0>;
+ clocks = <&slow_xtal>;
+ };
+
+Required properties for slow clock:
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks : shall encode the slow clk sources (see atmel datasheet).
+
+For example:
+ clk32k: slck {
+ compatible = "atmel,at91sam9x5-clk-slow";
+ #clock-cells = <0>;
+ clocks = <&slow_rc_osc &slow_osc>;
+ };
+
Required properties for PMC node:
- reg : defines the IO memory reserved for the PMC.
- #size-cells : shall be 0 (reg is used to encode clk id).
--
1.7.9.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 05/11] ARM: at91/dt: move sama5d3 SoC to the new main/slow clk model
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
` (3 preceding siblings ...)
2014-03-18 20:18 ` [PATCH 04/11] clk: at91: add slow clk documentation Boris BREZILLON
@ 2014-03-18 20:18 ` Boris BREZILLON
2014-03-18 20:18 ` [PATCH 06/11] ARM: at91/dt: add xtal frequencies to sama5d3xcm boards Boris BREZILLON
` (7 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-18 20:18 UTC (permalink / raw)
To: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot
Cc: devicetree, Boris BREZILLON, linux-doc, linux-kernel,
Boris BREZILLON, linux-arm-kernel
Replace the old main and clk definitions (fixed rate clk) by the new main and
slow clk subtree definition (ck = mux(rc_osc, osc)).
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
arch/arm/boot/dts/sama5d3.dtsi | 61 ++++++++++++++++++++++++++++++++++++----
1 file changed, 55 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index 3d5faf8..015797d 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -59,6 +59,18 @@
};
clocks {
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
adc_op_clk: adc_op_clk{
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -760,18 +772,29 @@
#size-cells = <0>;
#interrupt-cells = <1>;
- clk32k: slck {
- compatible = "fixed-clock";
+ main_rc_osc: main_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-main-rc-osc";
#clock-cells = <0>;
- clock-frequency = <32768>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MOSCRCS>;
+ clock-frequency = <12000000>;
+ clock-accuracy = <50000000>;
};
- main: mainck {
- compatible = "atmel,at91rm9200-clk-main";
+ main_osc: main_osc {
+ compatible = "atmel,at91rm9200-clk-main-osc";
#clock-cells = <0>;
interrupt-parent = <&pmc>;
interrupts = <AT91_PMC_MOSCS>;
- clocks = <&clk32k>;
+ clocks = <&main_xtal>;
+ };
+
+ main: mainck {
+ compatible = "atmel,at91sam9x5-clk-main";
+ #clock-cells = <0>;
+ interrupt-parent = <&pmc>;
+ interrupts = <AT91_PMC_MOSCSELS>;
+ clocks = <&main_rc_osc &main_osc>;
};
plla: pllack {
@@ -1100,6 +1123,32 @@
status = "disabled";
};
+ sckc@fffffe50 {
+ compatible = "atmel,at91sam9x5-sckc";
+ reg = <0xfffffe50 0x4>;
+
+ slow_rc_osc: slow_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-accuracy = <50000000>;
+ atmel,startup-time-usec = <75>;
+ };
+
+ slow_osc: slow_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-osc";
+ #clock-cells = <0>;
+ clocks = <&slow_xtal>;
+ atmel,startup-time-usec = <1200000>;
+ };
+
+ clk32k: slowck {
+ compatible = "atmel,at91sam9x5-clk-slow";
+ #clock-cells = <0>;
+ clocks = <&slow_rc_osc &slow_osc>;
+ };
+ };
+
rtc@fffffeb0 {
compatible = "atmel,at91rm9200-rtc";
reg = <0xfffffeb0 0x30>;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 06/11] ARM: at91/dt: add xtal frequencies to sama5d3xcm boards
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
` (4 preceding siblings ...)
2014-03-18 20:18 ` [PATCH 05/11] ARM: at91/dt: move sama5d3 SoC to the new main/slow clk model Boris BREZILLON
@ 2014-03-18 20:18 ` Boris BREZILLON
2014-03-18 20:18 ` [PATCH 07/11] ARM: at91/dt: add xtal frequencies to sama5d3 xplained board Boris BREZILLON
` (6 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-18 20:18 UTC (permalink / raw)
To: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot
Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel,
Boris BREZILLON, Boris BREZILLON
Define crystal frequencies of sama5d3xcm boards.
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
arch/arm/boot/dts/sama5d3xcm.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm/boot/dts/sama5d3xcm.dtsi b/arch/arm/boot/dts/sama5d3xcm.dtsi
index f55ed07..b320fad 100644
--- a/arch/arm/boot/dts/sama5d3xcm.dtsi
+++ b/arch/arm/boot/dts/sama5d3xcm.dtsi
@@ -18,6 +18,16 @@
reg = <0x20000000 0x20000000>;
};
+ clocks {
+ slow_xtal: slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal: main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
ahb {
apb {
spi0: spi@f0004000 {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 07/11] ARM: at91/dt: add xtal frequencies to sama5d3 xplained board
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
` (5 preceding siblings ...)
2014-03-18 20:18 ` [PATCH 06/11] ARM: at91/dt: add xtal frequencies to sama5d3xcm boards Boris BREZILLON
@ 2014-03-18 20:18 ` Boris BREZILLON
2014-03-18 20:18 ` [PATCH 08/11] ARM: at91/dt: move at91sam9261 SoC to the new main clock model Boris BREZILLON
` (5 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-18 20:18 UTC (permalink / raw)
To: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot
Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel,
Boris BREZILLON, Boris BREZILLON
Define crystal properties of sama5d3 xplained board.
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
arch/arm/boot/dts/at91-sama5d3_xplained.dts | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
index ce13755..df5b707 100644
--- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts
+++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
@@ -21,6 +21,16 @@
reg = <0x20000000 0x10000000>;
};
+ clocks {
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
ahb {
apb {
mmc0: mmc@f0000000 {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 08/11] ARM: at91/dt: move at91sam9261 SoC to the new main clock model
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
` (6 preceding siblings ...)
2014-03-18 20:18 ` [PATCH 07/11] ARM: at91/dt: add xtal frequencies to sama5d3 xplained board Boris BREZILLON
@ 2014-03-18 20:18 ` Boris BREZILLON
[not found] ` <1395173924-3648-9-git-send-email-b.brezillon.dev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-03-18 20:18 ` [PATCH 09/11] ARM: at91/dt: define main xtal frequency of the at91sam9261ek board Boris BREZILLON
` (4 subsequent siblings)
12 siblings, 1 reply; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-18 20:18 UTC (permalink / raw)
To: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot
Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel,
Boris BREZILLON
Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
---
arch/arm/boot/dts/at91sam9261.dtsi | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi
index e21dda0..e00fabc 100644
--- a/arch/arm/boot/dts/at91sam9261.dtsi
+++ b/arch/arm/boot/dts/at91sam9261.dtsi
@@ -45,6 +45,14 @@
reg = <0x20000000 0x08000000>;
};
+ clocks {
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -534,7 +542,7 @@
compatible = "atmel,at91rm9200-clk-main";
#clock-cells = <0>;
interrupts-extended = <&pmc AT91_PMC_MOSCS>;
- clocks = <&clk32k>;
+ clocks = <&main_xtal>;
};
plla: pllack {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 09/11] ARM: at91/dt: define main xtal frequency of the at91sam9261ek board
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
` (7 preceding siblings ...)
2014-03-18 20:18 ` [PATCH 08/11] ARM: at91/dt: move at91sam9261 SoC to the new main clock model Boris BREZILLON
@ 2014-03-18 20:18 ` Boris BREZILLON
2014-03-20 9:24 ` Jean-Jacques Hiblot
2014-03-18 20:18 ` [PATCH 10/11] ARM: at91/dt: move at91sam9rl SoC to the new slow/main clock models Boris BREZILLON
` (3 subsequent siblings)
12 siblings, 1 reply; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-18 20:18 UTC (permalink / raw)
To: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot
Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel,
Boris BREZILLON
Define at91sam9261ek main crystal frequency.
Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
---
arch/arm/boot/dts/at91sam9261ek.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/at91sam9261ek.dts b/arch/arm/boot/dts/at91sam9261ek.dts
index 2ce527e..7175986 100644
--- a/arch/arm/boot/dts/at91sam9261ek.dts
+++ b/arch/arm/boot/dts/at91sam9261ek.dts
@@ -29,6 +29,10 @@
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <18432000>;
};
+
+ main_xtal: main_xtal {
+ clock-frequency = <18432000>;
+ };
};
ahb {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 09/11] ARM: at91/dt: define main xtal frequency of the at91sam9261ek board
2014-03-18 20:18 ` [PATCH 09/11] ARM: at91/dt: define main xtal frequency of the at91sam9261ek board Boris BREZILLON
@ 2014-03-20 9:24 ` Jean-Jacques Hiblot
2014-03-20 9:50 ` Boris BREZILLON
0 siblings, 1 reply; 20+ messages in thread
From: Jean-Jacques Hiblot @ 2014-03-20 9:24 UTC (permalink / raw)
To: Boris BREZILLON
Cc: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot, devicetree, linux-doc,
Linux Kernel Mailing List, linux-arm-kernel@lists.infradead.org,
Boris BREZILLON
2014-03-18 21:18 GMT+01:00 Boris BREZILLON <brezillonboris@gmail.com>:
>
> Define at91sam9261ek main crystal frequency.
>
> Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
> ---
> arch/arm/boot/dts/at91sam9261ek.dts | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm/boot/dts/at91sam9261ek.dts b/arch/arm/boot/dts/at91sam9261ek.dts
> index 2ce527e..7175986 100644
> --- a/arch/arm/boot/dts/at91sam9261ek.dts
> +++ b/arch/arm/boot/dts/at91sam9261ek.dts
> @@ -29,6 +29,10 @@
> compatible = "atmel,osc", "fixed-clock";
> clock-frequency = <18432000>;
> };
> +
> + main_xtal: main_xtal {
> + clock-frequency = <18432000>;
> + };
> };
>
> ahb {
> --
> 1.7.9.5
>
You forgot to remove the old fixed-clock definition for the main_clock: clock@0
Otherwise:
Acked-by: Jean-Jacques HIBLOT <jjhiblot@traphandler.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 09/11] ARM: at91/dt: define main xtal frequency of the at91sam9261ek board
2014-03-20 9:24 ` Jean-Jacques Hiblot
@ 2014-03-20 9:50 ` Boris BREZILLON
2014-03-20 10:09 ` Jean-Jacques Hiblot
0 siblings, 1 reply; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-20 9:50 UTC (permalink / raw)
To: Jean-Jacques Hiblot, Boris BREZILLON
Cc: Nicolas Ferre, Mike Turquette, Alexandre Belloni, devicetree,
linux-doc, Linux Kernel Mailing List,
linux-arm-kernel@lists.infradead.org
Le 20/03/2014 10:24, Jean-Jacques Hiblot a écrit :
> 2014-03-18 21:18 GMT+01:00 Boris BREZILLON <brezillonboris@gmail.com>:
>> Define at91sam9261ek main crystal frequency.
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
>> ---
>> arch/arm/boot/dts/at91sam9261ek.dts | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/at91sam9261ek.dts b/arch/arm/boot/dts/at91sam9261ek.dts
>> index 2ce527e..7175986 100644
>> --- a/arch/arm/boot/dts/at91sam9261ek.dts
>> +++ b/arch/arm/boot/dts/at91sam9261ek.dts
>> @@ -29,6 +29,10 @@
>> compatible = "atmel,osc", "fixed-clock";
>> clock-frequency = <18432000>;
>> };
>> +
>> + main_xtal: main_xtal {
>> + clock-frequency = <18432000>;
>> + };
>> };
>>
>> ahb {
>> --
>> 1.7.9.5
>>
> You forgot to remove the old fixed-clock definition for the main_clock: clock@0
We need this clock when CCF is disabled (when using the old at91 clk
implementation).
I'm afraid we'll have to keep it until we move all sam9 SoCs and boards
to CCF (and DT).
Best Regards,
Boris
>
> Otherwise:
> Acked-by: Jean-Jacques HIBLOT <jjhiblot@traphandler.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 09/11] ARM: at91/dt: define main xtal frequency of the at91sam9261ek board
2014-03-20 9:50 ` Boris BREZILLON
@ 2014-03-20 10:09 ` Jean-Jacques Hiblot
0 siblings, 0 replies; 20+ messages in thread
From: Jean-Jacques Hiblot @ 2014-03-20 10:09 UTC (permalink / raw)
To: Boris BREZILLON
Cc: devicetree, Jean-Jacques Hiblot, linux-doc, Nicolas Ferre,
Linux Kernel Mailing List, Alexandre Belloni, Mike Turquette,
Boris BREZILLON, linux-arm-kernel@lists.infradead.org
That's right. I keep forgetting this.
2014-03-20 10:50 GMT+01:00 Boris BREZILLON <b.brezillon.dev@gmail.com>:
>
> Le 20/03/2014 10:24, Jean-Jacques Hiblot a écrit :
>
>> 2014-03-18 21:18 GMT+01:00 Boris BREZILLON <brezillonboris@gmail.com>:
>>>
>>> Define at91sam9261ek main crystal frequency.
>>>
>>> Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
>>> ---
>>> arch/arm/boot/dts/at91sam9261ek.dts | 4 ++++
>>> 1 file changed, 4 insertions(+)
>>>
>>> diff --git a/arch/arm/boot/dts/at91sam9261ek.dts
>>> b/arch/arm/boot/dts/at91sam9261ek.dts
>>> index 2ce527e..7175986 100644
>>> --- a/arch/arm/boot/dts/at91sam9261ek.dts
>>> +++ b/arch/arm/boot/dts/at91sam9261ek.dts
>>> @@ -29,6 +29,10 @@
>>> compatible = "atmel,osc", "fixed-clock";
>>> clock-frequency = <18432000>;
>>> };
>>> +
>>> + main_xtal: main_xtal {
>>> + clock-frequency = <18432000>;
>>> + };
>>> };
>>>
>>> ahb {
>>> --
>>> 1.7.9.5
>>>
>> You forgot to remove the old fixed-clock definition for the main_clock:
>> clock@0
>
>
> We need this clock when CCF is disabled (when using the old at91 clk
> implementation).
> I'm afraid we'll have to keep it until we move all sam9 SoCs and boards to
> CCF (and DT).
>
> Best Regards,
>
> Boris
>
>>
>> Otherwise:
>> Acked-by: Jean-Jacques HIBLOT <jjhiblot@traphandler.com>
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 10/11] ARM: at91/dt: move at91sam9rl SoC to the new slow/main clock models
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
` (8 preceding siblings ...)
2014-03-18 20:18 ` [PATCH 09/11] ARM: at91/dt: define main xtal frequency of the at91sam9261ek board Boris BREZILLON
@ 2014-03-18 20:18 ` Boris BREZILLON
[not found] ` <1395173924-3648-11-git-send-email-b.brezillon.dev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-03-18 20:18 ` [PATCH 11/11] ARM: at91/dt: define sam9rlek crystal frequencies Boris BREZILLON
` (2 subsequent siblings)
12 siblings, 1 reply; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-18 20:18 UTC (permalink / raw)
To: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot
Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel,
Boris BREZILLON
Move at91sam9rl SoC to the new main/slow clock model.
Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
---
arch/arm/boot/dts/at91sam9rl.dtsi | 45 ++++++++++++++++++++++++++++++++-----
1 file changed, 39 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi
index 63e1784..b367047 100644
--- a/arch/arm/boot/dts/at91sam9rl.dtsi
+++ b/arch/arm/boot/dts/at91sam9rl.dtsi
@@ -48,6 +48,20 @@
reg = <0x20000000 0x04000000>;
};
+ clocks {
+ slow_xtal: slow_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ main_xtal: main_xtal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -548,12 +562,6 @@
#size-cells = <0>;
#interrupt-cells = <1>;
- clk32k: slck {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <32768>;
- };
-
main: mainck {
compatible = "atmel,at91rm9200-clk-main";
#clock-cells = <0>;
@@ -769,6 +777,31 @@
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
status = "disabled";
};
+
+ sckc@fffffd50 {
+ compatible = "atmel,at91sam9x5-sckc";
+
+ slow_osc: slow_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-osc";
+ #clock-cells = <0>;
+ atmel,startup-time-usec = <1200000>;
+ clocks = <&slow_xtal>;
+ };
+
+ slow_rc_osc: slow_rc_osc {
+ compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
+ #clock-cells = <0>;
+ atmel,startup-time-usec = <75>;
+ clock-frequency = <32768>;
+ clock-accuracy = <50000000>;
+ };
+
+ clk32k: slck {
+ compatible = "atmel,at91sam9x5-clk-slow";
+ #clock-cells = <0>;
+ clocks = <&slow_rc_osc &slow_osc>;
+ };
+ };
};
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 11/11] ARM: at91/dt: define sam9rlek crystal frequencies
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
` (9 preceding siblings ...)
2014-03-18 20:18 ` [PATCH 10/11] ARM: at91/dt: move at91sam9rl SoC to the new slow/main clock models Boris BREZILLON
@ 2014-03-18 20:18 ` Boris BREZILLON
2014-03-19 15:40 ` Alexandre Belloni
2014-03-19 8:19 ` [PATCH 00/11] ARM: at91: rework main and slow clk implementation Jean-Jacques Hiblot
[not found] ` <3485B87A-1832-4EE3-8613-B5165C282397@jcrosoft.com>
12 siblings, 1 reply; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-18 20:18 UTC (permalink / raw)
To: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot
Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel,
Boris BREZILLON
Define at91sam9rlek crystal frequencies.
Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
---
arch/arm/boot/dts/at91sam9rlek.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/at91sam9rlek.dts b/arch/arm/boot/dts/at91sam9rlek.dts
index cddb378..85b68b9 100644
--- a/arch/arm/boot/dts/at91sam9rlek.dts
+++ b/arch/arm/boot/dts/at91sam9rlek.dts
@@ -25,6 +25,14 @@
#size-cells = <1>;
ranges;
+ slow_xtal: slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal: main_xtal {
+ clock-frequency = <12000000>;
+ };
+
main_clock: clock {
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <12000000>;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 11/11] ARM: at91/dt: define sam9rlek crystal frequencies
2014-03-18 20:18 ` [PATCH 11/11] ARM: at91/dt: define sam9rlek crystal frequencies Boris BREZILLON
@ 2014-03-19 15:40 ` Alexandre Belloni
0 siblings, 0 replies; 20+ messages in thread
From: Alexandre Belloni @ 2014-03-19 15:40 UTC (permalink / raw)
To: Boris BREZILLON
Cc: Nicolas Ferre, Mike Turquette, Jean-Jacques Hiblot, devicetree,
linux-doc, linux-kernel, linux-arm-kernel, Boris BREZILLON
On 18/03/2014 at 21:18:44 +0100, Boris BREZILLON wrote :
> Define at91sam9rlek crystal frequencies.
>
> Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> ---
> arch/arm/boot/dts/at91sam9rlek.dts | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/arch/arm/boot/dts/at91sam9rlek.dts b/arch/arm/boot/dts/at91sam9rlek.dts
> index cddb378..85b68b9 100644
> --- a/arch/arm/boot/dts/at91sam9rlek.dts
> +++ b/arch/arm/boot/dts/at91sam9rlek.dts
> @@ -25,6 +25,14 @@
> #size-cells = <1>;
> ranges;
>
> + slow_xtal: slow_xtal {
> + clock-frequency = <32768>;
> + };
> +
> + main_xtal: main_xtal {
> + clock-frequency = <12000000>;
> + };
> +
> main_clock: clock {
> compatible = "atmel,osc", "fixed-clock";
> clock-frequency = <12000000>;
> --
> 1.7.9.5
>
--
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 00/11] ARM: at91: rework main and slow clk implementation
2014-03-18 20:18 [PATCH 00/11] ARM: at91: rework main and slow clk implementation Boris BREZILLON
` (10 preceding siblings ...)
2014-03-18 20:18 ` [PATCH 11/11] ARM: at91/dt: define sam9rlek crystal frequencies Boris BREZILLON
@ 2014-03-19 8:19 ` Jean-Jacques Hiblot
[not found] ` <3485B87A-1832-4EE3-8613-B5165C282397@jcrosoft.com>
12 siblings, 0 replies; 20+ messages in thread
From: Jean-Jacques Hiblot @ 2014-03-19 8:19 UTC (permalink / raw)
To: Boris BREZILLON
Cc: devicetree, Mike Turquette, linux-doc, Boris BREZILLON,
Nicolas Ferre, Linux Kernel Mailing List, Alexandre Belloni,
Jean-Jacques Hiblot, linux-arm-kernel@lists.infradead.org
Hi Boris,
2014-03-18 21:18 GMT+01:00 Boris BREZILLON <brezillonboris@gmail.com>:
>
> Hello,
>
> This series introduce the real clock model (as described in atmel datasheets)
> for slow and main clocks.
>
> The modifications introduced by this series break the DT compat, but, as the
> at91 CCF based implementation is pretty new (introduced in 3.14 only for sama5
> eval boards) I think it won't impact a lot of users.
>
> I tested it on sama5d3.
> Alexandre, Jean-Jacques, could you test this series on your eval boards
> (sam9261ek and sam9rlek) so that we can move to this new model and hopefully
> consider the at91 clk DT binding as (almost :-)) stable.
I'll try to do this this week, but I can make no promise
>
> Jean-Jacques, as you can see I reworked my first implementation as you
> suggested, do you want me to add your Signed-off-by in the next version ?
Nop, you did the job, not I.
>
> Mike, if this series is accepted, I'd like to get it merged as soon as possible
> to prevent other developpers from using a deprecated DT binding.
>
> Best Regards,
>
> Boris
>
> Boris BREZILLON (11):
> clk: at91: rework main clk implementation
> clk: at91: update main clk documentation
> clk: at91: add slow clks driver
> clk: at91: add slow clk documentation
> ARM: at91/dt: move sama5d3 SoC to the new main/slow clk model
> ARM: at91/dt: add xtal frequencies to sama5d3xcm boards
> ARM: at91/dt: add xtal frequencies to sama5d3 xplained board
> ARM: at91/dt: move at91sam9261 SoC to the new main clock model
> ARM: at91/dt: define main xtal frequency of the at91sam9261ek board
> ARM: at91/dt: move at91sam9rl SoC to the new slow/main clock models
> ARM: at91/dt: define sam9rlek crystal frequencies
>
> .../devicetree/bindings/clock/at91-clock.txt | 128 ++++-
> arch/arm/boot/dts/at91-sama5d3_xplained.dts | 10 +
> arch/arm/boot/dts/at91sam9261.dtsi | 10 +-
> arch/arm/boot/dts/at91sam9261ek.dts | 4 +
> arch/arm/boot/dts/at91sam9rl.dtsi | 45 +-
> arch/arm/boot/dts/at91sam9rlek.dts | 8 +
> arch/arm/boot/dts/sama5d3.dtsi | 61 +-
> arch/arm/boot/dts/sama5d3xcm.dtsi | 10 +
> drivers/clk/at91/Makefile | 4 +-
> drivers/clk/at91/clk-main.c | 581 +++++++++++++++++---
> drivers/clk/at91/clk-slow.c | 467 ++++++++++++++++
> drivers/clk/at91/pmc.c | 12 +
> drivers/clk/at91/pmc.h | 9 +
> drivers/clk/at91/sckc.c | 57 ++
> drivers/clk/at91/sckc.h | 22 +
> include/linux/clk/at91_pmc.h | 1 +
> 16 files changed, 1342 insertions(+), 87 deletions(-)
> create mode 100644 drivers/clk/at91/clk-slow.c
> create mode 100644 drivers/clk/at91/sckc.c
> create mode 100644 drivers/clk/at91/sckc.h
>
> --
> 1.7.9.5
>
^ permalink raw reply [flat|nested] 20+ messages in thread
[parent not found: <3485B87A-1832-4EE3-8613-B5165C282397@jcrosoft.com>]
* Re: [PATCH 00/11] ARM: at91: rework main and slow clk implementation
[not found] ` <3485B87A-1832-4EE3-8613-B5165C282397@jcrosoft.com>
@ 2014-03-19 9:48 ` Boris BREZILLON
0 siblings, 0 replies; 20+ messages in thread
From: Boris BREZILLON @ 2014-03-19 9:48 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD
Cc: Nicolas Ferre, Mike Turquette, Alexandre Belloni,
Jean-Jacques Hiblot, devicetree@vger.kernel.org,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
Hello Jean-Christophe,
Le 19/03/2014 07:06, Jean-Christophe PLAGNIOL-VILLARD a écrit :
> You must keep me in Cc
I always did, this is an oversight.
>
> first and last warning
Now, this is my turn.
I don't like to be threatened, especially when this message is only sent
to me.
BTW, last warning, then what ?
Now let's talk about your attitude.
Regarding this specific series: I sent you several versions of the at91
CCF based
clk implementation and you never fully reviewed those series (despite
the fact you
told me you would do it), why are you so interested in the at91 CCF
implementation
now ?
Moreover, most of the time when you review a patchset your remarks are
far from
constructive, and we always have to ask you several times to get a real
explanation.
I'm not telling you're wrong when you "NACK" something, but explaining
the reasons
are part of your maintainer's job.
This being said, I'll take care to keep you in Cc of all at91 related
patches.
Best Regards,
Boris
>
> On Mar 19, 2014, at 4:18 AM, Boris BREZILLON <brezillonboris@gmail.com> wrote:
>
>> Hello,
>>
>> This series introduce the real clock model (as described in atmel datasheets)
>> for slow and main clocks.
>>
>> The modifications introduced by this series break the DT compat, but, as the
>> at91 CCF based implementation is pretty new (introduced in 3.14 only for sama5
>> eval boards) I think it won't impact a lot of users.
>>
>> I tested it on sama5d3.
>> Alexandre, Jean-Jacques, could you test this series on your eval boards
>> (sam9261ek and sam9rlek) so that we can move to this new model and hopefully
>> consider the at91 clk DT binding as (almost :-)) stable.
>>
>> Jean-Jacques, as you can see I reworked my first implementation as you
>> suggested, do you want me to add your Signed-off-by in the next version ?
>>
>> Mike, if this series is accepted, I'd like to get it merged as soon as possible
>> to prevent other developpers from using a deprecated DT binding.
>>
>> Best Regards,
>>
>> Boris
>>
>> Boris BREZILLON (11):
>> clk: at91: rework main clk implementation
>> clk: at91: update main clk documentation
>> clk: at91: add slow clks driver
>> clk: at91: add slow clk documentation
>> ARM: at91/dt: move sama5d3 SoC to the new main/slow clk model
>> ARM: at91/dt: add xtal frequencies to sama5d3xcm boards
>> ARM: at91/dt: add xtal frequencies to sama5d3 xplained board
>> ARM: at91/dt: move at91sam9261 SoC to the new main clock model
>> ARM: at91/dt: define main xtal frequency of the at91sam9261ek board
>> ARM: at91/dt: move at91sam9rl SoC to the new slow/main clock models
>> ARM: at91/dt: define sam9rlek crystal frequencies
>>
>> .../devicetree/bindings/clock/at91-clock.txt | 128 ++++-
>> arch/arm/boot/dts/at91-sama5d3_xplained.dts | 10 +
>> arch/arm/boot/dts/at91sam9261.dtsi | 10 +-
>> arch/arm/boot/dts/at91sam9261ek.dts | 4 +
>> arch/arm/boot/dts/at91sam9rl.dtsi | 45 +-
>> arch/arm/boot/dts/at91sam9rlek.dts | 8 +
>> arch/arm/boot/dts/sama5d3.dtsi | 61 +-
>> arch/arm/boot/dts/sama5d3xcm.dtsi | 10 +
>> drivers/clk/at91/Makefile | 4 +-
>> drivers/clk/at91/clk-main.c | 581 +++++++++++++++++---
>> drivers/clk/at91/clk-slow.c | 467 ++++++++++++++++
>> drivers/clk/at91/pmc.c | 12 +
>> drivers/clk/at91/pmc.h | 9 +
>> drivers/clk/at91/sckc.c | 57 ++
>> drivers/clk/at91/sckc.h | 22 +
>> include/linux/clk/at91_pmc.h | 1 +
>> 16 files changed, 1342 insertions(+), 87 deletions(-)
>> create mode 100644 drivers/clk/at91/clk-slow.c
>> create mode 100644 drivers/clk/at91/sckc.c
>> create mode 100644 drivers/clk/at91/sckc.h
>>
>> --
>> 1.7.9.5
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 20+ messages in thread