[PATCH] timer: fttmr010: return a previously deleted driver now ported to DM

Sergei Antonov saproj at gmail.com
Mon Feb 13 18:34:36 CET 2023


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 at gmail.com>
---
 drivers/timer/Kconfig          |  7 +++
 drivers/timer/Makefile         |  1 +
 drivers/timer/fttmr010_timer.c | 92 ++++++++++++++++++++++++++++++++++
 include/faraday/fttmr010.h     |  1 +
 4 files changed, 101 insertions(+)
 create mode 100644 drivers/timer/fttmr010_timer.c

diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index f32bd16227e3..915b2af160c1 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -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
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index 3c92113fc6fd..cdc20f5e946e 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -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
index 000000000000..b6289e646109
--- /dev/null
+++ b/drivers/timer/fttmr010_timer.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert at 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,
+};
diff --git a/include/faraday/fttmr010.h b/include/faraday/fttmr010.h
index ec1c9895f57c..5b1bef38c77d 100644
--- a/include/faraday/fttmr010.h
+++ b/include/faraday/fttmr010.h
@@ -26,6 +26,7 @@ struct fttmr010 {
 	unsigned int	cr;			/* 0x30 */
 	unsigned int	interrupt_state;	/* 0x34 */
 	unsigned int	interrupt_mask;		/* 0x38 */
+	unsigned int	revision;		/* 0x3c */
 };
 
 /*
-- 
2.34.1



More information about the U-Boot mailing list