timer: fttmr010: return a previously deleted driver now ported to DM
authorSergei Antonov <saproj@gmail.com>
Mon, 13 Feb 2023 17:34:36 +0000 (20:34 +0300)
committerTom Rini <trini@konsulko.com>
Mon, 6 Mar 2023 22:03:56 +0000 (17:03 -0500)
The fttmr010 timer driver was deleted by
commit 29fc6f24926e ("ARM: remove a320evb board support")
The original source file was: arch/arm/cpu/arm920t/a320/timer.c

Return the driver to the codebase in a DM compatible form.
A platform using fttmr010 will be submitted later.

This hardware is described in the datasheet [1], starting from page 348.
According to the datasheet, there is a Revision Register at offset 0x3C,
which is not present in 'struct fttmr010'. Add it and debug() print
revision in probe function.

[1]
https://bitbucket.org/Kasreyn/mkrom-uc7112lx/src/master/documents/FIC8120_DS_v1.2.pdf

Signed-off-by: Sergei Antonov <saproj@gmail.com>
drivers/timer/Kconfig
drivers/timer/Makefile
drivers/timer/fttmr010_timer.c [new file with mode: 0644]
include/faraday/fttmr010.h

index f32bd16..915b2af 100644 (file)
@@ -145,6 +145,13 @@ config DESIGNWARE_APB_TIMER
          Enables support for the Designware APB Timer driver. This timer is
          present on Altera SoCFPGA SoCs.
 
+config FTTMR010_TIMER
+       bool "Faraday Technology timer support"
+       depends on TIMER
+       help
+         Select this to enable support for the timer found on
+         devices using Faraday Technology's IP.
+
 config GXP_TIMER
        bool "HPE GXP Timer"
        depends on TIMER
index 3c92113..cdc20f5 100644 (file)
@@ -13,6 +13,7 @@ obj-$(CONFIG_$(SPL_)ATMEL_PIT_TIMER) += atmel_pit_timer.o
 obj-$(CONFIG_$(SPL_)ATMEL_TCB_TIMER) += atmel_tcb_timer.o
 obj-$(CONFIG_CADENCE_TTC_TIMER)        += cadence-ttc.o
 obj-$(CONFIG_DESIGNWARE_APB_TIMER)     += dw-apb-timer.o
+obj-$(CONFIG_FTTMR010_TIMER)   += fttmr010_timer.o
 obj-$(CONFIG_GXP_TIMER)                += gxp-timer.o
 obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
 obj-$(CONFIG_NOMADIK_MTU_TIMER)        += nomadik-mtu-timer.o
diff --git a/drivers/timer/fttmr010_timer.c b/drivers/timer/fttmr010_timer.c
new file mode 100644 (file)
index 0000000..b6289e6
--- /dev/null
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.com>
+ *
+ * 23/08/2022 Port to DM
+ */
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <dm/ofnode.h>
+#include <faraday/fttmr010.h>
+#include <asm/global_data.h>
+
+#define TIMER_LOAD_VAL 0xffffffff
+
+struct fttmr010_timer_priv {
+       struct fttmr010 __iomem *regs;
+};
+
+static u64 fttmr010_timer_get_count(struct udevice *dev)
+{
+       struct fttmr010_timer_priv *priv = dev_get_priv(dev);
+       struct fttmr010 *tmr = priv->regs;
+       u32 now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter);
+
+       /* increment tbu if tbl has rolled over */
+       if (now < gd->arch.tbl)
+               gd->arch.tbu++;
+       gd->arch.tbl = now;
+
+       return ((u64)gd->arch.tbu << 32) | gd->arch.tbl;
+}
+
+static int fttmr010_timer_probe(struct udevice *dev)
+{
+       struct fttmr010_timer_priv *priv = dev_get_priv(dev);
+       struct fttmr010 *tmr;
+       unsigned int cr;
+
+       priv->regs = dev_read_addr_ptr(dev);
+       if (!priv->regs)
+               return -EINVAL;
+       tmr = priv->regs;
+
+       debug("Faraday FTTMR010 timer revision 0x%08X\n", readl(&tmr->revision));
+
+       /* disable timers */
+       writel(0, &tmr->cr);
+
+       /* setup timer */
+       writel(TIMER_LOAD_VAL, &tmr->timer3_load);
+       writel(TIMER_LOAD_VAL, &tmr->timer3_counter);
+       writel(0, &tmr->timer3_match1);
+       writel(0, &tmr->timer3_match2);
+
+       /* we don't want timer to issue interrupts */
+       writel(FTTMR010_TM3_MATCH1 |
+              FTTMR010_TM3_MATCH2 |
+              FTTMR010_TM3_OVERFLOW,
+              &tmr->interrupt_mask);
+
+       cr = readl(&tmr->cr);
+       cr |= FTTMR010_TM3_CLOCK;       /* use external clock */
+       cr |= FTTMR010_TM3_ENABLE;
+       writel(cr, &tmr->cr);
+
+       gd->arch.tbl = 0;
+       gd->arch.tbu = 0;
+
+       return 0;
+}
+
+static const struct timer_ops fttmr010_timer_ops = {
+       .get_count = fttmr010_timer_get_count,
+};
+
+static const struct udevice_id fttmr010_timer_ids[] = {
+       { .compatible = "faraday,fttmr010-timer" },
+       {}
+};
+
+U_BOOT_DRIVER(fttmr010_timer) = {
+       .name = "fttmr010_timer",
+       .id = UCLASS_TIMER,
+       .of_match = fttmr010_timer_ids,
+       .priv_auto = sizeof(struct fttmr010_timer_priv),
+       .probe = fttmr010_timer_probe,
+       .ops = &fttmr010_timer_ops,
+};
index ec1c989..5b1bef3 100644 (file)
@@ -26,6 +26,7 @@ struct fttmr010 {
        unsigned int    cr;                     /* 0x30 */
        unsigned int    interrupt_state;        /* 0x34 */
        unsigned int    interrupt_mask;         /* 0x38 */
+       unsigned int    revision;               /* 0x3c */
 };
 
 /*