Skip to content

Commit

Permalink
drivers: timer: Add TI DM TIMER support
Browse files Browse the repository at this point in the history
TI DM Timer is a dual mode timer, J721E R5 cores does not have
arch timer for systick. Add DM Timer for systick timer
support.

Signed-off-by: Prashanth S <slpp95prashanth@yahoo.com>
  • Loading branch information
slpp95prashanth committed Aug 3, 2023
1 parent 96bc04f commit 2ef71cf
Show file tree
Hide file tree
Showing 6 changed files with 273 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/timer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ zephyr_library_sources_ifdef(CONFIG_ESP32C3_SYS_TIMER esp32c3_sys_timer.c)
zephyr_library_sources_ifdef(CONFIG_GECKO_BURTC_TIMER gecko_burtc_timer.c)
zephyr_library_sources_ifdef(CONFIG_HPET_TIMER hpet.c)
zephyr_library_sources_ifdef(CONFIG_ITE_IT8XXX2_TIMER ite_it8xxx2_timer.c)
zephyr_library_sources_ifdef(CONFIG_OMAP_DM_TIMER ti_dmtimer.c)
zephyr_library_sources_ifdef(CONFIG_LEON_GPTIMER leon_gptimer.c)
zephyr_library_sources_ifdef(CONFIG_LITEX_TIMER litex_timer.c)
zephyr_library_sources_ifdef(CONFIG_MCHP_XEC_RTOS_TIMER mchp_xec_rtos_timer.c)
Expand Down
1 change: 1 addition & 0 deletions drivers/timer/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ source "drivers/timer/Kconfig.esp32c3_sys"
source "drivers/timer/Kconfig.gecko"
source "drivers/timer/Kconfig.hpet"
source "drivers/timer/Kconfig.ite_it8xxx2"
source "drivers/timer/Kconfig.omap_dm_timer"
source "drivers/timer/Kconfig.leon_gptimer"
source "drivers/timer/Kconfig.litex"
source "drivers/timer/Kconfig.mchp_xec_rtos"
Expand Down
12 changes: 12 additions & 0 deletions drivers/timer/Kconfig.omap_dm_timer
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright (C) 2023 BeagleBoard.org Foundation
# Copyright (C) 2023 S Prashanth
#
# SPDX-License-Identifier: Apache-2.0

config OMAP_DM_TIMER
bool "TI Dual-Mode Timer"
default y
depends on DT_HAS_TI_AM654_DMTIMER_ENABLED
help
This module implements a kernel device driver for TI dual-mode timer. This
driver provides system tick interface
79 changes: 79 additions & 0 deletions drivers/timer/ti_dmtimer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* Copyright (C) 2023 BeagleBoard.org Foundation
* Copyright (C) 2023 S Prashanth
*
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT ti_am654_dmtimer

#include <zephyr/device.h>
#include <zephyr/drivers/timer/system_timer.h>
#include <zephyr/irq.h>
#include <zephyr/sys_clock.h>
#include <zephyr/kernel.h>

#include <zephyr/drivers/timer/ti_dmtimer.h>

#define CYC_PER_TICK ((uint32_t)(sys_clock_hw_cycles_per_sec() \
/ CONFIG_SYS_CLOCK_TICKS_PER_SEC))

static struct k_spinlock lock;

void ti_dmtimer_isr(void *data)
{
k_spinlock_key_t key = k_spin_lock(&lock);

sys_write32(BIT(TI_DM_TIMER_IRQENABLE_SET_OVF_EN_FLAG_SHIFT),
TI_DM_TIMER_IRQSTATUS);
sys_write32(0xffffffff - CYC_PER_TICK, TI_DM_TIMER_TLDR);
sys_write32(0xffffffff - CYC_PER_TICK, TI_DM_TIMER_TCRR);
sys_write32(BIT(TI_DM_TIMER_TCLR_ST_SHIFT), TI_DM_TIMER_TCLR);

k_spin_unlock(&lock, key);

sys_clock_announce(1);
}

void sys_clock_set_timeout(int32_t ticks, bool idle)
{
}

uint32_t sys_clock_cycle_get_32(void)
{
k_spinlock_key_t key = k_spin_lock(&lock);

uint32_t tcrr_count = sys_read32(TI_DM_TIMER_TCRR);

k_spin_unlock(&lock, key);

return (tcrr_count - (0xffffffff - CYC_PER_TICK));
}

unsigned int sys_clock_elapsed(void)
{
return 0;
}

static int sys_clock_driver_init(void)
{
IRQ_CONNECT(TI_DM_TIMER_IRQ_NUM, TI_DM_TIMER_IRQ_PRIO,
ti_dmtimer_isr, NULL, TI_DM_TIMER_IRQ_FLAGS);

sys_write32(BIT(TI_DM_TIMER_IRQENABLE_SET_OVF_EN_FLAG_SHIFT),
TI_DM_TIMER_IRQENABLE_SET);

sys_write32(0xffffffff - CYC_PER_TICK, TI_DM_TIMER_TLDR);
sys_write32(0xffffffff - CYC_PER_TICK, TI_DM_TIMER_TCRR);

sys_write32(0, TI_DM_TIMER_TPIR);
sys_write32(0, TI_DM_TIMER_TNIR);

sys_write32(BIT(TI_DM_TIMER_TCLR_ST_SHIFT), TI_DM_TIMER_TCLR);

irq_enable(TI_DM_TIMER_IRQ_NUM);

return 0;
}

SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
22 changes: 22 additions & 0 deletions dts/bindings/timer/ti,am654-dmtimer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright (C) 2023 BeagleBoard.org Foundation
# Copyright (C) 2023 S Prashanth
#
# SPDX-License-Identifier: Apache-2.0

description: TI dual-mode Timer

compatible: "ti,am654-dmtimer"

include: base.yaml

properties:
reg-shift:
type: int
required: true
description: quantity to shift the register offsets by

reg:
required: true

interrupts:
required: true
158 changes: 158 additions & 0 deletions include/zephyr/drivers/timer/ti_dmtimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/* Copyright (C) 2023 BeagleBoard.org Foundation
* Copyright (C) 2023 S Prashanth
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_DRIVERS_TIMERS_TI_DMTIMER_H_
#define ZEPHYR_DRIVERS_TIMERS_TI_DMTIMER_H_

#include <zephyr/devicetree.h>

#define TI_DM_TIMER_BASE_ADDR DT_REG_ADDR(DT_INST(0, ti_am654_dmtimer))

#define TI_DM_TIMER_IRQ_NUM DT_IRQN(DT_INST(0, ti_am654_dmtimer))
#define TI_DM_TIMER_IRQ_PRIO DT_IRQ(DT_INST(0, ti_am654_dmtimer), priority)
#define TI_DM_TIMER_IRQ_FLAGS DT_IRQ(DT_INST(0, ti_am654_dmtimer), flags)

#define TI_DM_TIMER_TIDR (TI_DM_TIMER_BASE_ADDR + 0x00)
#define TI_DM_TIMER_TIOCP_CFG (TI_DM_TIMER_BASE_ADDR + 0x10)
#define TI_DM_TIMER_IRQ_EOI (TI_DM_TIMER_BASE_ADDR + 0x20)
#define TI_DM_TIMER_IRQSTATUS_RAW (TI_DM_TIMER_BASE_ADDR + 0x24)
#define TI_DM_TIMER_IRQSTATUS (TI_DM_TIMER_BASE_ADDR + 0x28)
#define TI_DM_TIMER_IRQENABLE_SET (TI_DM_TIMER_BASE_ADDR + 0x2c)
#define TI_DM_TIMER_IRQENABLE_CLR (TI_DM_TIMER_BASE_ADDR + 0x30)
#define TI_DM_TIMER_IRQWAKEEN (TI_DM_TIMER_BASE_ADDR + 0x34)
#define TI_DM_TIMER_TCLR (TI_DM_TIMER_BASE_ADDR + 0x38)
#define TI_DM_TIMER_TCRR (TI_DM_TIMER_BASE_ADDR + 0x3c)
#define TI_DM_TIMER_TLDR (TI_DM_TIMER_BASE_ADDR + 0x40)
#define TI_DM_TIMER_TTGR (TI_DM_TIMER_BASE_ADDR + 0x44)
#define TI_DM_TIMER_TWPS (TI_DM_TIMER_BASE_ADDR + 0x48)
#define TI_DM_TIMER_TMAR (TI_DM_TIMER_BASE_ADDR + 0x4c)
#define TI_DM_TIMER_TCAR1 (TI_DM_TIMER_BASE_ADDR + 0x50)
#define TI_DM_TIMER_TSICR (TI_DM_TIMER_BASE_ADDR + 0x54)
#define TI_DM_TIMER_TCAR2 (TI_DM_TIMER_BASE_ADDR + 0x58)
#define TI_DM_TIMER_TPIR (TI_DM_TIMER_BASE_ADDR + 0x5c)
#define TI_DM_TIMER_TNIR (TI_DM_TIMER_BASE_ADDR + 0x60)
#define TI_DM_TIMER_TCVR (TI_DM_TIMER_BASE_ADDR + 0x64)
#define TI_DM_TIMER_TOCR (TI_DM_TIMER_BASE_ADDR + 0x68)
#define TI_DM_TIMER_TOWR (TI_DM_TIMER_BASE_ADDR + 0x6c)

#define TI_DM_TIMER_IRQSTATUS_RAW_MAT_IT_FLAG_SHIFT (0)
#define TI_DM_TIMER_IRQSTATUS_RAW_MAT_IT_FLAG_MASK (0x00000001)

#define TI_DM_TIMER_IRQSTATUS_RAW_OVF_IT_FLAG_SHIFT (1)
#define TI_DM_TIMER_IRQSTATUS_RAW_OVF_IT_FLAG_MASK (0x00000002)

#define TI_DM_TIMER_IRQSTATUS_RAW_TCAR_IT_FLAG_SHIFT (2)
#define TI_DM_TIMER_IRQSTATUS_RAW_TCAR_IT_FLAG_MASK (0x00000004)

#define TI_DM_TIMER_IRQSTATUS_RAW_RESERVED_SHIFT (3)
#define TI_DM_TIMER_IRQSTATUS_RAW_RESERVED_MASK (0xfffffff8)

#define TI_DM_TIMER_IRQSTATUS_MAT_IT_FLAG_SHIFT (0)
#define TI_DM_TIMER_IRQSTATUS_MAT_IT_FLAG_MASK (0x00000001)

#define TI_DM_TIMER_IRQSTATUS_OVF_IT_FLAG_SHIFT (1)
#define TI_DM_TIMER_IRQSTATUS_OVF_IT_FLAG_MASK (0x00000002)

#define TI_DM_TIMER_IRQSTATUS_TCAR_IT_FLAG_SHIFT (2)
#define TI_DM_TIMER_IRQSTATUS_TCAR_IT_FLAG_MASK (0x00000004)

#define TI_DM_TIMER_IRQSTATUS_RESERVED_SHIFT (3)
#define TI_DM_TIMER_IRQSTATUS_RESERVED_MASK (0xfffffff8)

#define TI_DM_TIMER_IRQENABLE_SET_MAT_EN_FLAG_SHIFT (0)
#define TI_DM_TIMER_IRQENABLE_SET_MAT_EN_FLAG_MASK (0x00000001)

#define TI_DM_TIMER_IRQENABLE_SET_OVF_EN_FLAG_SHIFT (1)
#define TI_DM_TIMER_IRQENABLE_SET_OVF_EN_FLAG_MASK (0x00000002)

#define TI_DM_TIMER_IRQENABLE_SET_TCAR_EN_FLAG_SHIFT (2)
#define TI_DM_TIMER_IRQENABLE_SET_TCAR_EN_FLAG_MASK (0x00000004)

#define TI_DM_TIMER_IRQENABLE_SET_RESERVED_SHIFT (3)
#define TI_DM_TIMER_IRQENABLE_SET_RESERVED_MASK (0xfffffff8)

#define TI_DM_TIMER_IRQENABLE_CLR_MAT_EN_FLAG_SHIFT (0)
#define TI_DM_TIMER_IRQENABLE_CLR_MAT_EN_FLAG_MASK (0x00000001)

#define TI_DM_TIMER_IRQENABLE_CLR_OVF_EN_FLAG_SHIFT (1)
#define TI_DM_TIMER_IRQENABLE_CLR_OVF_EN_FLAG_MASK (0x00000002)

#define TI_DM_TIMER_IRQENABLE_CLR_TCAR_EN_FLAG_SHIFT (2)
#define TI_DM_TIMER_IRQENABLE_CLR_TCAR_EN_FLAG_MASK (0x00000004)

#define TI_DM_TIMER_IRQENABLE_CLR_RESERVED_SHIFT (3)
#define TI_DM_TIMER_IRQENABLE_CLR_RESERVED_MASK (0xfffffff8)

#define TI_DM_TIMER_TCLR_TCM_SHIFT (8)
#define TI_DM_TIMER_TCLR_TCM_MASK (0x00000300)
#define TI_DM_TIMER_TCLR_TCM_TCM_VALUE_0X0 (0)
#define TI_DM_TIMER_TCLR_TCM_TCM_VALUE_0X1 (1)
#define TI_DM_TIMER_TCLR_TCM_TCM_VALUE_0X2 (2)
#define TI_DM_TIMER_TCLR_TCM_TCM_VALUE_0X3 (3)

#define TI_DM_TIMER_TCLR_ST_SHIFT (0)
#define TI_DM_TIMER_TCLR_ST_MASK (0x00000001)
#define TI_DM_TIMER_TCLR_ST_ST_VALUE_0 (0)
#define TI_DM_TIMER_TCLR_ST_ST_VALUE_1 (1)

#define TI_DM_TIMER_TCLR_PTV_SHIFT (2)
#define TI_DM_TIMER_TCLR_PTV_MASK (0x0000001c)

#define TI_DM_TIMER_TCLR_CE_SHIFT (6)
#define TI_DM_TIMER_TCLR_CE_MASK (0x00000040)
#define TI_DM_TIMER_TCLR_CE_CE_VALUE_0 (0)
#define TI_DM_TIMER_TCLR_CE_CE_VALUE_1 (1)

#define TI_DM_TIMER_TCLR_AR_SHIFT (1)
#define TI_DM_TIMER_TCLR_AR_MASK (0x00000002)
#define TI_DM_TIMER_TCLR_AR_AR_VALUE_0 (0)
#define TI_DM_TIMER_TCLR_AR_AR_VALUE_1 (1)

#define TI_DM_TIMER_TCLR_RESERVED_SHIFT (15)
#define TI_DM_TIMER_TCLR_RESERVED_MASK (0xffff8000)

#define TI_DM_TIMER_TCLR_CAPT_MODE_SHIFT (13)
#define TI_DM_TIMER_TCLR_CAPT_MODE_MASK (0x00002000)
#define TI_DM_TIMER_TCLR_CAPT_MODE_CAPT_MODE_VALUE_0 (0)
#define TI_DM_TIMER_TCLR_CAPT_MODE_CAPT_MODE_VALUE_1 (1)

#define TI_DM_TIMER_TCLR_TRG_SHIFT (10)
#define TI_DM_TIMER_TCLR_TRG_MASK (0x00000c00)
#define TI_DM_TIMER_TCLR_TRG_TRG_VALUE_0X0 (0)
#define TI_DM_TIMER_TCLR_TRG_TRG_VALUE_0X1 (1)
#define TI_DM_TIMER_TCLR_TRG_TRG_VALUE_0X2 (2)
#define TI_DM_TIMER_TCLR_TRG_TRG_VALUE_0X3 (3)

#define TI_DM_TIMER_TCLR_PT_SHIFT (12)
#define TI_DM_TIMER_TCLR_PT_MASK (0x00001000)
#define TI_DM_TIMER_TCLR_PT_PT_VALUE_0 (0)
#define TI_DM_TIMER_TCLR_PT_PT_VALUE_1 (1)

#define TI_DM_TIMER_TCLR_SCPWM_SHIFT (7)
#define TI_DM_TIMER_TCLR_SCPWM_MASK (0x00000080)
#define TI_DM_TIMER_TCLR_SCPWM_SCPWM_VALUE_0 (0)
#define TI_DM_TIMER_TCLR_SCPWM_SCPWM_VALUE_1 (1)

#define TI_DM_TIMER_TCLR_PRE_SHIFT (5)
#define TI_DM_TIMER_TCLR_PRE_MASK (0x00000020)
#define TI_DM_TIMER_TCLR_PRE_PRE_VALUE_0 (0)
#define TI_DM_TIMER_TCLR_PRE_PRE_VALUE_1 (1)

#define TI_DM_TIMER_TCLR_GPO_CFG_SHIFT (14)
#define TI_DM_TIMER_TCLR_GPO_CFG_MASK (0x00004000)
#define TI_DM_TIMER_TCLR_GPO_CFG_GPO_CFG_0 (0)
#define TI_DM_TIMER_TCLR_GPO_CFG_GPO_CFG_1 (1UL)

#define TI_DM_TIMER_TCRR_TIMER_COUNTER_SHIFT (0)
#define TI_DM_TIMER_TCRR_TIMER_COUNTER_MASK (0xffffffff)

#define TI_DM_TIMER_TLDR_LOAD_VALUE_SHIFT (0)
#define TI_DM_TIMER_TLDR_LOAD_VALUE_MASK (0xffffffff)

#define TI_DM_TIMER_TMAR_COMPARE_VALUE_SHIFT (0)
#define TI_DM_TIMER_TMAR_COMPARE_VALUE_MASK (0xffffffff)

#endif /* ZEPHYR_DRIVERS_TIMERS_TI_DMTIMER_H_ */

0 comments on commit 2ef71cf

Please sign in to comment.