From 2c0bdcacf3bb4045d96d567c114606acf1a9b257 Mon Sep 17 00:00:00 2001 From: Sergei Antonov Date: Mon, 13 Feb 2023 20:34:36 +0300 Subject: [PATCH] timer: fttmr010: return a previously deleted driver now ported to DM 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 --- 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 f32bd16227..915b2af160 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 3c92113fc6..cdc20f5e94 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 0000000000..b6289e6461 --- /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 + * + * 23/08/2022 Port to DM + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#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 ec1c9895f5..5b1bef38c7 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.39.5