This patch adds support for other Marvell Armada SoC's, supporting the
25MHz fixed clock operation, like the Armada XP etc.

Signed-off-by: Stefan Roese <s...@denx.de>
---
v2:
- Use timer_conv_64() in timer_early_get_count()

 drivers/timer/Kconfig       |  5 ++++-
 drivers/timer/orion-timer.c | 42 ++++++++++++++++++++++++++++++++++---
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 404929014810..b0814acca3fb 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -197,8 +197,11 @@ config OMAP_TIMER
 config ORION_TIMER
        bool "Orion timer support"
        depends on TIMER
+       default y if ARCH_KIRKWOOD || (ARCH_MVEBU && ARMADA_32BIT)
+       select TIMER_EARLY if ARCH_MVEBU
        help
-         Select this to enable an timer for Orion devices.
+         Select this to enable an timer for Orion and Armada devices
+         like Armada XP etc.
 
 config RISCV_TIMER
        bool "RISC-V timer support"
diff --git a/drivers/timer/orion-timer.c b/drivers/timer/orion-timer.c
index d7d1a1b24462..14f318e57d4d 100644
--- a/drivers/timer/orion-timer.c
+++ b/drivers/timer/orion-timer.c
@@ -11,10 +11,34 @@
 #define TIMER0_RELOAD          0x10
 #define TIMER0_VAL             0x14
 
+enum input_clock_type {
+       INPUT_CLOCK_NON_FIXED,
+       INPUT_CLOCK_25MHZ,      /* input clock rate is fixed to 25MHz */
+};
+
 struct orion_timer_priv {
        void *base;
 };
 
+#define MVEBU_TIMER_FIXED_RATE_25MHZ   25000000
+
+/**
+ * timer_early_get_rate() - Get the timer rate before driver model
+ */
+unsigned long notrace timer_early_get_rate(void)
+{
+       return MVEBU_TIMER_FIXED_RATE_25MHZ;
+}
+
+/**
+ * timer_early_get_count() - Get the timer count before driver model
+ *
+ */
+u64 notrace timer_early_get_count(void)
+{
+       return timer_conv_64(~readl(MVEBU_TIMER_BASE + TIMER0_VAL));
+}
+
 static uint64_t orion_timer_get_count(struct udevice *dev)
 {
        struct orion_timer_priv *priv = dev_get_priv(dev);
@@ -25,6 +49,7 @@ static uint64_t orion_timer_get_count(struct udevice *dev)
 static int orion_timer_probe(struct udevice *dev)
 {
        struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+       enum input_clock_type type = dev_get_driver_data(dev);
        struct orion_timer_priv *priv = dev_get_priv(dev);
 
        priv->base = devfdt_remap_addr_index(dev, 0);
@@ -33,11 +58,20 @@ static int orion_timer_probe(struct udevice *dev)
                return -ENOMEM;
        }
 
-       uc_priv->clock_rate = CONFIG_SYS_TCLK;
-
        writel(~0, priv->base + TIMER0_VAL);
        writel(~0, priv->base + TIMER0_RELOAD);
 
+       if (type == INPUT_CLOCK_25MHZ) {
+               /*
+                * On Armada XP / 38x ..., the 25MHz clock source needs to
+                * be enabled
+                */
+               setbits_le32(priv->base + TIMER_CTRL, BIT(11));
+               uc_priv->clock_rate = MVEBU_TIMER_FIXED_RATE_25MHZ;
+       } else {
+               uc_priv->clock_rate = CONFIG_SYS_TCLK;
+       }
+
        /* enable timer */
        setbits_le32(priv->base + TIMER_CTRL, TIMER0_EN | TIMER0_RELOAD_EN);
 
@@ -49,7 +83,9 @@ static const struct timer_ops orion_timer_ops = {
 };
 
 static const struct udevice_id orion_timer_ids[] = {
-       { .compatible = "marvell,orion-timer" },
+       { .compatible = "marvell,orion-timer", .data = INPUT_CLOCK_NON_FIXED },
+       { .compatible = "marvell,armada-370-timer", .data = INPUT_CLOCK_25MHZ },
+       { .compatible = "marvell,armada-xp-timer", .data = INPUT_CLOCK_25MHZ },
        {}
 };
 
-- 
2.37.3

Reply via email to