18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Mediatek SoCs General-Purpose Timer handling. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2014 Matthias Brugger 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Matthias Brugger <matthias.bgg@gmail.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/clockchips.h> 138c2ecf20Sopenharmony_ci#include <linux/clocksource.h> 148c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 158c2ecf20Sopenharmony_ci#include <linux/irqreturn.h> 168c2ecf20Sopenharmony_ci#include <linux/sched_clock.h> 178c2ecf20Sopenharmony_ci#include <linux/slab.h> 188c2ecf20Sopenharmony_ci#include "timer-of.h" 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define TIMER_CLK_EVT (1) 218c2ecf20Sopenharmony_ci#define TIMER_CLK_SRC (2) 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define TIMER_SYNC_TICKS (3) 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci/* gpt */ 268c2ecf20Sopenharmony_ci#define GPT_IRQ_EN_REG 0x00 278c2ecf20Sopenharmony_ci#define GPT_IRQ_ENABLE(val) BIT((val) - 1) 288c2ecf20Sopenharmony_ci#define GPT_IRQ_ACK_REG 0x08 298c2ecf20Sopenharmony_ci#define GPT_IRQ_ACK(val) BIT((val) - 1) 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define GPT_CTRL_REG(val) (0x10 * (val)) 328c2ecf20Sopenharmony_ci#define GPT_CTRL_OP(val) (((val) & 0x3) << 4) 338c2ecf20Sopenharmony_ci#define GPT_CTRL_OP_ONESHOT (0) 348c2ecf20Sopenharmony_ci#define GPT_CTRL_OP_REPEAT (1) 358c2ecf20Sopenharmony_ci#define GPT_CTRL_OP_FREERUN (3) 368c2ecf20Sopenharmony_ci#define GPT_CTRL_CLEAR (2) 378c2ecf20Sopenharmony_ci#define GPT_CTRL_ENABLE (1) 388c2ecf20Sopenharmony_ci#define GPT_CTRL_DISABLE (0) 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#define GPT_CLK_REG(val) (0x04 + (0x10 * (val))) 418c2ecf20Sopenharmony_ci#define GPT_CLK_SRC(val) (((val) & 0x1) << 4) 428c2ecf20Sopenharmony_ci#define GPT_CLK_SRC_SYS13M (0) 438c2ecf20Sopenharmony_ci#define GPT_CLK_SRC_RTC32K (1) 448c2ecf20Sopenharmony_ci#define GPT_CLK_DIV1 (0x0) 458c2ecf20Sopenharmony_ci#define GPT_CLK_DIV2 (0x1) 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define GPT_CNT_REG(val) (0x08 + (0x10 * (val))) 488c2ecf20Sopenharmony_ci#define GPT_CMP_REG(val) (0x0C + (0x10 * (val))) 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci/* system timer */ 518c2ecf20Sopenharmony_ci#define SYST_BASE (0x40) 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define SYST_CON (SYST_BASE + 0x0) 548c2ecf20Sopenharmony_ci#define SYST_VAL (SYST_BASE + 0x4) 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#define SYST_CON_REG(to) (timer_of_base(to) + SYST_CON) 578c2ecf20Sopenharmony_ci#define SYST_VAL_REG(to) (timer_of_base(to) + SYST_VAL) 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci/* 608c2ecf20Sopenharmony_ci * SYST_CON_EN: Clock enable. Shall be set to 618c2ecf20Sopenharmony_ci * - Start timer countdown. 628c2ecf20Sopenharmony_ci * - Allow timeout ticks being updated. 638c2ecf20Sopenharmony_ci * - Allow changing interrupt functions. 648c2ecf20Sopenharmony_ci * 658c2ecf20Sopenharmony_ci * SYST_CON_IRQ_EN: Set to allow interrupt. 668c2ecf20Sopenharmony_ci * 678c2ecf20Sopenharmony_ci * SYST_CON_IRQ_CLR: Set to clear interrupt. 688c2ecf20Sopenharmony_ci */ 698c2ecf20Sopenharmony_ci#define SYST_CON_EN BIT(0) 708c2ecf20Sopenharmony_ci#define SYST_CON_IRQ_EN BIT(1) 718c2ecf20Sopenharmony_ci#define SYST_CON_IRQ_CLR BIT(4) 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistatic void __iomem *gpt_sched_reg __read_mostly; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic void mtk_syst_ack_irq(struct timer_of *to) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci /* Clear and disable interrupt */ 788c2ecf20Sopenharmony_ci writel(SYST_CON_IRQ_CLR | SYST_CON_EN, SYST_CON_REG(to)); 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic irqreturn_t mtk_syst_handler(int irq, void *dev_id) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci struct clock_event_device *clkevt = dev_id; 848c2ecf20Sopenharmony_ci struct timer_of *to = to_timer_of(clkevt); 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci mtk_syst_ack_irq(to); 878c2ecf20Sopenharmony_ci clkevt->event_handler(clkevt); 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci return IRQ_HANDLED; 908c2ecf20Sopenharmony_ci} 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistatic int mtk_syst_clkevt_next_event(unsigned long ticks, 938c2ecf20Sopenharmony_ci struct clock_event_device *clkevt) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci struct timer_of *to = to_timer_of(clkevt); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci /* Enable clock to allow timeout tick update later */ 988c2ecf20Sopenharmony_ci writel(SYST_CON_EN, SYST_CON_REG(to)); 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci /* 1018c2ecf20Sopenharmony_ci * Write new timeout ticks. Timer shall start countdown 1028c2ecf20Sopenharmony_ci * after timeout ticks are updated. 1038c2ecf20Sopenharmony_ci */ 1048c2ecf20Sopenharmony_ci writel(ticks, SYST_VAL_REG(to)); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci /* Enable interrupt */ 1078c2ecf20Sopenharmony_ci writel(SYST_CON_EN | SYST_CON_IRQ_EN, SYST_CON_REG(to)); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci return 0; 1108c2ecf20Sopenharmony_ci} 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_cistatic int mtk_syst_clkevt_shutdown(struct clock_event_device *clkevt) 1138c2ecf20Sopenharmony_ci{ 1148c2ecf20Sopenharmony_ci /* Disable timer */ 1158c2ecf20Sopenharmony_ci writel(0, SYST_CON_REG(to_timer_of(clkevt))); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci return 0; 1188c2ecf20Sopenharmony_ci} 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistatic int mtk_syst_clkevt_resume(struct clock_event_device *clkevt) 1218c2ecf20Sopenharmony_ci{ 1228c2ecf20Sopenharmony_ci return mtk_syst_clkevt_shutdown(clkevt); 1238c2ecf20Sopenharmony_ci} 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cistatic int mtk_syst_clkevt_oneshot(struct clock_event_device *clkevt) 1268c2ecf20Sopenharmony_ci{ 1278c2ecf20Sopenharmony_ci return 0; 1288c2ecf20Sopenharmony_ci} 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_cistatic u64 notrace mtk_gpt_read_sched_clock(void) 1318c2ecf20Sopenharmony_ci{ 1328c2ecf20Sopenharmony_ci return readl_relaxed(gpt_sched_reg); 1338c2ecf20Sopenharmony_ci} 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_cistatic void mtk_gpt_clkevt_time_stop(struct timer_of *to, u8 timer) 1368c2ecf20Sopenharmony_ci{ 1378c2ecf20Sopenharmony_ci u32 val; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci val = readl(timer_of_base(to) + GPT_CTRL_REG(timer)); 1408c2ecf20Sopenharmony_ci writel(val & ~GPT_CTRL_ENABLE, timer_of_base(to) + 1418c2ecf20Sopenharmony_ci GPT_CTRL_REG(timer)); 1428c2ecf20Sopenharmony_ci} 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_cistatic void mtk_gpt_clkevt_time_setup(struct timer_of *to, 1458c2ecf20Sopenharmony_ci unsigned long delay, u8 timer) 1468c2ecf20Sopenharmony_ci{ 1478c2ecf20Sopenharmony_ci writel(delay, timer_of_base(to) + GPT_CMP_REG(timer)); 1488c2ecf20Sopenharmony_ci} 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_cistatic void mtk_gpt_clkevt_time_start(struct timer_of *to, 1518c2ecf20Sopenharmony_ci bool periodic, u8 timer) 1528c2ecf20Sopenharmony_ci{ 1538c2ecf20Sopenharmony_ci u32 val; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci /* Acknowledge interrupt */ 1568c2ecf20Sopenharmony_ci writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG); 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci val = readl(timer_of_base(to) + GPT_CTRL_REG(timer)); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci /* Clear 2 bit timer operation mode field */ 1618c2ecf20Sopenharmony_ci val &= ~GPT_CTRL_OP(0x3); 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci if (periodic) 1648c2ecf20Sopenharmony_ci val |= GPT_CTRL_OP(GPT_CTRL_OP_REPEAT); 1658c2ecf20Sopenharmony_ci else 1668c2ecf20Sopenharmony_ci val |= GPT_CTRL_OP(GPT_CTRL_OP_ONESHOT); 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci writel(val | GPT_CTRL_ENABLE | GPT_CTRL_CLEAR, 1698c2ecf20Sopenharmony_ci timer_of_base(to) + GPT_CTRL_REG(timer)); 1708c2ecf20Sopenharmony_ci} 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_cistatic int mtk_gpt_clkevt_shutdown(struct clock_event_device *clk) 1738c2ecf20Sopenharmony_ci{ 1748c2ecf20Sopenharmony_ci mtk_gpt_clkevt_time_stop(to_timer_of(clk), TIMER_CLK_EVT); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci return 0; 1778c2ecf20Sopenharmony_ci} 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_cistatic int mtk_gpt_clkevt_set_periodic(struct clock_event_device *clk) 1808c2ecf20Sopenharmony_ci{ 1818c2ecf20Sopenharmony_ci struct timer_of *to = to_timer_of(clk); 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci mtk_gpt_clkevt_time_stop(to, TIMER_CLK_EVT); 1848c2ecf20Sopenharmony_ci mtk_gpt_clkevt_time_setup(to, to->of_clk.period, TIMER_CLK_EVT); 1858c2ecf20Sopenharmony_ci mtk_gpt_clkevt_time_start(to, true, TIMER_CLK_EVT); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci return 0; 1888c2ecf20Sopenharmony_ci} 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_cistatic int mtk_gpt_clkevt_next_event(unsigned long event, 1918c2ecf20Sopenharmony_ci struct clock_event_device *clk) 1928c2ecf20Sopenharmony_ci{ 1938c2ecf20Sopenharmony_ci struct timer_of *to = to_timer_of(clk); 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci mtk_gpt_clkevt_time_stop(to, TIMER_CLK_EVT); 1968c2ecf20Sopenharmony_ci mtk_gpt_clkevt_time_setup(to, event, TIMER_CLK_EVT); 1978c2ecf20Sopenharmony_ci mtk_gpt_clkevt_time_start(to, false, TIMER_CLK_EVT); 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci return 0; 2008c2ecf20Sopenharmony_ci} 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cistatic irqreturn_t mtk_gpt_interrupt(int irq, void *dev_id) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci struct clock_event_device *clkevt = (struct clock_event_device *)dev_id; 2058c2ecf20Sopenharmony_ci struct timer_of *to = to_timer_of(clkevt); 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci /* Acknowledge timer0 irq */ 2088c2ecf20Sopenharmony_ci writel(GPT_IRQ_ACK(TIMER_CLK_EVT), timer_of_base(to) + GPT_IRQ_ACK_REG); 2098c2ecf20Sopenharmony_ci clkevt->event_handler(clkevt); 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci return IRQ_HANDLED; 2128c2ecf20Sopenharmony_ci} 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_cistatic void 2158c2ecf20Sopenharmony_ci__init mtk_gpt_setup(struct timer_of *to, u8 timer, u8 option) 2168c2ecf20Sopenharmony_ci{ 2178c2ecf20Sopenharmony_ci writel(GPT_CTRL_CLEAR | GPT_CTRL_DISABLE, 2188c2ecf20Sopenharmony_ci timer_of_base(to) + GPT_CTRL_REG(timer)); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci writel(GPT_CLK_SRC(GPT_CLK_SRC_SYS13M) | GPT_CLK_DIV1, 2218c2ecf20Sopenharmony_ci timer_of_base(to) + GPT_CLK_REG(timer)); 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci writel(0x0, timer_of_base(to) + GPT_CMP_REG(timer)); 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci writel(GPT_CTRL_OP(option) | GPT_CTRL_ENABLE, 2268c2ecf20Sopenharmony_ci timer_of_base(to) + GPT_CTRL_REG(timer)); 2278c2ecf20Sopenharmony_ci} 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_cistatic void mtk_gpt_enable_irq(struct timer_of *to, u8 timer) 2308c2ecf20Sopenharmony_ci{ 2318c2ecf20Sopenharmony_ci u32 val; 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci /* Disable all interrupts */ 2348c2ecf20Sopenharmony_ci writel(0x0, timer_of_base(to) + GPT_IRQ_EN_REG); 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci /* Acknowledge all spurious pending interrupts */ 2378c2ecf20Sopenharmony_ci writel(0x3f, timer_of_base(to) + GPT_IRQ_ACK_REG); 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci val = readl(timer_of_base(to) + GPT_IRQ_EN_REG); 2408c2ecf20Sopenharmony_ci writel(val | GPT_IRQ_ENABLE(timer), 2418c2ecf20Sopenharmony_ci timer_of_base(to) + GPT_IRQ_EN_REG); 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_cistatic struct timer_of to = { 2458c2ecf20Sopenharmony_ci .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK, 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci .clkevt = { 2488c2ecf20Sopenharmony_ci .name = "mtk-clkevt", 2498c2ecf20Sopenharmony_ci .rating = 300, 2508c2ecf20Sopenharmony_ci .cpumask = cpu_possible_mask, 2518c2ecf20Sopenharmony_ci }, 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci .of_irq = { 2548c2ecf20Sopenharmony_ci .flags = IRQF_TIMER | IRQF_IRQPOLL, 2558c2ecf20Sopenharmony_ci }, 2568c2ecf20Sopenharmony_ci}; 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_cistatic int __init mtk_syst_init(struct device_node *node) 2598c2ecf20Sopenharmony_ci{ 2608c2ecf20Sopenharmony_ci int ret; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci to.clkevt.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT; 2638c2ecf20Sopenharmony_ci to.clkevt.set_state_shutdown = mtk_syst_clkevt_shutdown; 2648c2ecf20Sopenharmony_ci to.clkevt.set_state_oneshot = mtk_syst_clkevt_oneshot; 2658c2ecf20Sopenharmony_ci to.clkevt.tick_resume = mtk_syst_clkevt_resume; 2668c2ecf20Sopenharmony_ci to.clkevt.set_next_event = mtk_syst_clkevt_next_event; 2678c2ecf20Sopenharmony_ci to.of_irq.handler = mtk_syst_handler; 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci ret = timer_of_init(node, &to); 2708c2ecf20Sopenharmony_ci if (ret) 2718c2ecf20Sopenharmony_ci return ret; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), 2748c2ecf20Sopenharmony_ci TIMER_SYNC_TICKS, 0xffffffff); 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci return 0; 2778c2ecf20Sopenharmony_ci} 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_cistatic int __init mtk_gpt_init(struct device_node *node) 2808c2ecf20Sopenharmony_ci{ 2818c2ecf20Sopenharmony_ci int ret; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci to.clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 2848c2ecf20Sopenharmony_ci to.clkevt.set_state_shutdown = mtk_gpt_clkevt_shutdown; 2858c2ecf20Sopenharmony_ci to.clkevt.set_state_periodic = mtk_gpt_clkevt_set_periodic; 2868c2ecf20Sopenharmony_ci to.clkevt.set_state_oneshot = mtk_gpt_clkevt_shutdown; 2878c2ecf20Sopenharmony_ci to.clkevt.tick_resume = mtk_gpt_clkevt_shutdown; 2888c2ecf20Sopenharmony_ci to.clkevt.set_next_event = mtk_gpt_clkevt_next_event; 2898c2ecf20Sopenharmony_ci to.of_irq.handler = mtk_gpt_interrupt; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci ret = timer_of_init(node, &to); 2928c2ecf20Sopenharmony_ci if (ret) 2938c2ecf20Sopenharmony_ci return ret; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci /* Configure clock source */ 2968c2ecf20Sopenharmony_ci mtk_gpt_setup(&to, TIMER_CLK_SRC, GPT_CTRL_OP_FREERUN); 2978c2ecf20Sopenharmony_ci clocksource_mmio_init(timer_of_base(&to) + GPT_CNT_REG(TIMER_CLK_SRC), 2988c2ecf20Sopenharmony_ci node->name, timer_of_rate(&to), 300, 32, 2998c2ecf20Sopenharmony_ci clocksource_mmio_readl_up); 3008c2ecf20Sopenharmony_ci gpt_sched_reg = timer_of_base(&to) + GPT_CNT_REG(TIMER_CLK_SRC); 3018c2ecf20Sopenharmony_ci sched_clock_register(mtk_gpt_read_sched_clock, 32, timer_of_rate(&to)); 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci /* Configure clock event */ 3048c2ecf20Sopenharmony_ci mtk_gpt_setup(&to, TIMER_CLK_EVT, GPT_CTRL_OP_REPEAT); 3058c2ecf20Sopenharmony_ci clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), 3068c2ecf20Sopenharmony_ci TIMER_SYNC_TICKS, 0xffffffff); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci mtk_gpt_enable_irq(&to, TIMER_CLK_EVT); 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci return 0; 3118c2ecf20Sopenharmony_ci} 3128c2ecf20Sopenharmony_ciTIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init); 3138c2ecf20Sopenharmony_ciTIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init); 314