From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lubomir Rintel Date: Tue, 17 Nov 2020 22:00:06 +0100 Subject: [PATCH RFC 08/20] timer: Add Ingenic JZ4730 timer driver In-Reply-To: <20201117210018.751469-1-lkundrak@v3.sk> References: <20201117210018.751469-1-lkundrak@v3.sk> Message-ID: <20201117210018.751469-9-lkundrak@v3.sk> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de This adds support for a timer block on JZ4730 SoC. Signed-off-by: Lubomir Rintel --- drivers/timer/Kconfig | 8 ++++ drivers/timer/Makefile | 1 + drivers/timer/jz4730_timer.c | 83 ++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 drivers/timer/jz4730_timer.c diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 80743a25519..9d5a84c03ea 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -110,6 +110,14 @@ config DESIGNWARE_APB_TIMER Enables support for the Designware APB Timer driver. This timer is present on Altera SoCFPGA SoCs. +config JZ4730_TIMER + bool "Ingenic JZ4730 timer support" + depends on TIMER + default y if SOC_JZ4730 + help + Select this to enable support for the timer found on + devices based on the Ingenic JZ4730 SoC. + config MPC83XX_TIMER bool "MPC83xx timer support" depends on TIMER diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index eb5c48cc6ce..67529c78e59 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence-ttc.o obj-$(CONFIG_DESIGNWARE_APB_TIMER) += dw-apb-timer.o +obj-$(CONFIG_JZ4730_TIMER) += jz4730_timer.o obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o obj-$(CONFIG_NOMADIK_MTU_TIMER) += nomadik-mtu-timer.o obj-$(CONFIG_OMAP_TIMER) += omap-timer.o diff --git a/drivers/timer/jz4730_timer.c b/drivers/timer/jz4730_timer.c new file mode 100644 index 00000000000..d2c77a20993 --- /dev/null +++ b/drivers/timer/jz4730_timer.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4730 Timer driver. + * + * Copyright (c) 2020 Lubomir Rintel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHANNEL_ID 0 + +#define OST_TER (0x00) +#define OST_TRDR(n) (0x10 + ((n) * 0x20)) +#define OST_TCNT(n) (0x14 + ((n) * 0x20)) +#define OST_TCSR(n) (0x18 + ((n) * 0x20)) +#define OST_TCRB(n) (0x1c + ((n) * 0x20)) + +#define OST_TCSR_CKS_PCLK_256 0x0003 + +struct jz4730_timer_priv { + void __iomem *base; +}; + +static u64 jz4730_timer_get_count(struct udevice *dev) +{ + struct jz4730_timer_priv *priv = dev_get_priv(dev); + u32 val = readl(priv->base + OST_TCNT(CHANNEL_ID)); + + return timer_conv_64(U32_MAX - val); +} + +static int jz4730_timer_probe(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct jz4730_timer_priv *priv = dev_get_priv(dev); + struct clk clk; + int ret; + + priv->base = dev_remap_addr(dev); + if (!priv->base) + return -EINVAL; + + ret = clk_get_by_name(dev, "pclk", &clk); + if (ret) + return ret; + + uc_priv->clock_rate = clk_get_rate(&clk); + uc_priv->clock_rate /= 256; + + writew(OST_TCSR_CKS_PCLK_256, priv->base + OST_TCSR(CHANNEL_ID)); + writel(U32_MAX, priv->base + OST_TRDR(CHANNEL_ID)); + writel(U32_MAX, priv->base + OST_TCNT(CHANNEL_ID)); + writeb(BIT(CHANNEL_ID), priv->base + OST_TER); + + return 0; +} + +static const struct timer_ops jz4730_timer_ops = { + .get_count = jz4730_timer_get_count, +}; + +static const struct udevice_id jz4730_timer_ids[] = { + { .compatible = "ingenic,jz4730-tcu" }, + { } +}; + +U_BOOT_DRIVER(jz4730_timer) = { + .name = "jz4730_timer", + .id = UCLASS_TIMER, + .of_match = jz4730_timer_ids, + .priv_auto_alloc_size = sizeof(struct jz4730_timer_priv), + .probe = jz4730_timer_probe, + .ops = &jz4730_timer_ops, + .flags = DM_FLAG_PRE_RELOC, +}; -- 2.28.0