1*52762fbdSTony Lindgren // SPDX-License-Identifier: GPL-2.0+ 2*52762fbdSTony Lindgren #include <linux/clk.h> 3*52762fbdSTony Lindgren #include <linux/clocksource.h> 4*52762fbdSTony Lindgren #include <linux/clockchips.h> 5*52762fbdSTony Lindgren #include <linux/interrupt.h> 6*52762fbdSTony Lindgren #include <linux/io.h> 7*52762fbdSTony Lindgren #include <linux/iopoll.h> 8*52762fbdSTony Lindgren #include <linux/err.h> 9*52762fbdSTony Lindgren #include <linux/of.h> 10*52762fbdSTony Lindgren #include <linux/of_address.h> 11*52762fbdSTony Lindgren #include <linux/of_irq.h> 12*52762fbdSTony Lindgren #include <linux/sched_clock.h> 13*52762fbdSTony Lindgren 14*52762fbdSTony Lindgren #include <linux/clk/clk-conf.h> 15*52762fbdSTony Lindgren 16*52762fbdSTony Lindgren #include <clocksource/timer-ti-dm.h> 17*52762fbdSTony Lindgren #include <dt-bindings/bus/ti-sysc.h> 18*52762fbdSTony Lindgren 19*52762fbdSTony Lindgren /* For type1, set SYSC_OMAP2_CLOCKACTIVITY for fck off on idle, l4 clock on */ 20*52762fbdSTony Lindgren #define DMTIMER_TYPE1_ENABLE ((1 << 9) | (SYSC_IDLE_SMART << 3) | \ 21*52762fbdSTony Lindgren SYSC_OMAP2_ENAWAKEUP | SYSC_OMAP2_AUTOIDLE) 22*52762fbdSTony Lindgren 23*52762fbdSTony Lindgren #define DMTIMER_TYPE2_ENABLE (SYSC_IDLE_SMART_WKUP << 2) 24*52762fbdSTony Lindgren #define DMTIMER_RESET_WAIT 100000 25*52762fbdSTony Lindgren 26*52762fbdSTony Lindgren #define DMTIMER_INST_DONT_CARE ~0U 27*52762fbdSTony Lindgren 28*52762fbdSTony Lindgren static int counter_32k; 29*52762fbdSTony Lindgren static u32 clocksource; 30*52762fbdSTony Lindgren static u32 clockevent; 31*52762fbdSTony Lindgren 32*52762fbdSTony Lindgren /* 33*52762fbdSTony Lindgren * Subset of the timer registers we use. Note that the register offsets 34*52762fbdSTony Lindgren * depend on the timer revision detected. 35*52762fbdSTony Lindgren */ 36*52762fbdSTony Lindgren struct dmtimer_systimer { 37*52762fbdSTony Lindgren void __iomem *base; 38*52762fbdSTony Lindgren u8 sysc; 39*52762fbdSTony Lindgren u8 irq_stat; 40*52762fbdSTony Lindgren u8 irq_ena; 41*52762fbdSTony Lindgren u8 pend; 42*52762fbdSTony Lindgren u8 load; 43*52762fbdSTony Lindgren u8 counter; 44*52762fbdSTony Lindgren u8 ctrl; 45*52762fbdSTony Lindgren u8 wakeup; 46*52762fbdSTony Lindgren u8 ifctrl; 47*52762fbdSTony Lindgren unsigned long rate; 48*52762fbdSTony Lindgren }; 49*52762fbdSTony Lindgren 50*52762fbdSTony Lindgren struct dmtimer_clockevent { 51*52762fbdSTony Lindgren struct clock_event_device dev; 52*52762fbdSTony Lindgren struct dmtimer_systimer t; 53*52762fbdSTony Lindgren u32 period; 54*52762fbdSTony Lindgren }; 55*52762fbdSTony Lindgren 56*52762fbdSTony Lindgren struct dmtimer_clocksource { 57*52762fbdSTony Lindgren struct clocksource dev; 58*52762fbdSTony Lindgren struct dmtimer_systimer t; 59*52762fbdSTony Lindgren unsigned int loadval; 60*52762fbdSTony Lindgren }; 61*52762fbdSTony Lindgren 62*52762fbdSTony Lindgren /* Assumes v1 ip if bits [31:16] are zero */ 63*52762fbdSTony Lindgren static bool dmtimer_systimer_revision1(struct dmtimer_systimer *t) 64*52762fbdSTony Lindgren { 65*52762fbdSTony Lindgren u32 tidr = readl_relaxed(t->base); 66*52762fbdSTony Lindgren 67*52762fbdSTony Lindgren return !(tidr >> 16); 68*52762fbdSTony Lindgren } 69*52762fbdSTony Lindgren 70*52762fbdSTony Lindgren static int __init dmtimer_systimer_type1_reset(struct dmtimer_systimer *t) 71*52762fbdSTony Lindgren { 72*52762fbdSTony Lindgren void __iomem *syss = t->base + OMAP_TIMER_V1_SYS_STAT_OFFSET; 73*52762fbdSTony Lindgren int ret; 74*52762fbdSTony Lindgren u32 l; 75*52762fbdSTony Lindgren 76*52762fbdSTony Lindgren writel_relaxed(BIT(1) | BIT(2), t->base + t->ifctrl); 77*52762fbdSTony Lindgren ret = readl_poll_timeout_atomic(syss, l, l & BIT(0), 100, 78*52762fbdSTony Lindgren DMTIMER_RESET_WAIT); 79*52762fbdSTony Lindgren 80*52762fbdSTony Lindgren return ret; 81*52762fbdSTony Lindgren } 82*52762fbdSTony Lindgren 83*52762fbdSTony Lindgren /* Note we must use io_base instead of func_base for type2 OCP regs */ 84*52762fbdSTony Lindgren static int __init dmtimer_systimer_type2_reset(struct dmtimer_systimer *t) 85*52762fbdSTony Lindgren { 86*52762fbdSTony Lindgren void __iomem *sysc = t->base + t->sysc; 87*52762fbdSTony Lindgren u32 l; 88*52762fbdSTony Lindgren 89*52762fbdSTony Lindgren l = readl_relaxed(sysc); 90*52762fbdSTony Lindgren l |= BIT(0); 91*52762fbdSTony Lindgren writel_relaxed(l, sysc); 92*52762fbdSTony Lindgren 93*52762fbdSTony Lindgren return readl_poll_timeout_atomic(sysc, l, !(l & BIT(0)), 100, 94*52762fbdSTony Lindgren DMTIMER_RESET_WAIT); 95*52762fbdSTony Lindgren } 96*52762fbdSTony Lindgren 97*52762fbdSTony Lindgren static int __init dmtimer_systimer_reset(struct dmtimer_systimer *t) 98*52762fbdSTony Lindgren { 99*52762fbdSTony Lindgren int ret; 100*52762fbdSTony Lindgren 101*52762fbdSTony Lindgren if (dmtimer_systimer_revision1(t)) 102*52762fbdSTony Lindgren ret = dmtimer_systimer_type1_reset(t); 103*52762fbdSTony Lindgren else 104*52762fbdSTony Lindgren ret = dmtimer_systimer_type2_reset(t); 105*52762fbdSTony Lindgren if (ret < 0) { 106*52762fbdSTony Lindgren pr_err("%s failed with %i\n", __func__, ret); 107*52762fbdSTony Lindgren 108*52762fbdSTony Lindgren return ret; 109*52762fbdSTony Lindgren } 110*52762fbdSTony Lindgren 111*52762fbdSTony Lindgren return 0; 112*52762fbdSTony Lindgren } 113*52762fbdSTony Lindgren 114*52762fbdSTony Lindgren static const struct of_device_id counter_match_table[] = { 115*52762fbdSTony Lindgren { .compatible = "ti,omap-counter32k" }, 116*52762fbdSTony Lindgren { /* Sentinel */ }, 117*52762fbdSTony Lindgren }; 118*52762fbdSTony Lindgren 119*52762fbdSTony Lindgren /* 120*52762fbdSTony Lindgren * Check if the SoC als has a usable working 32 KiHz counter. The 32 KiHz 121*52762fbdSTony Lindgren * counter is handled by timer-ti-32k, but we need to detect it as it 122*52762fbdSTony Lindgren * affects the preferred dmtimer system timer configuration. There is 123*52762fbdSTony Lindgren * typically no use for a dmtimer clocksource if the 32 KiHz counter is 124*52762fbdSTony Lindgren * present, except on am437x as described below. 125*52762fbdSTony Lindgren */ 126*52762fbdSTony Lindgren static void __init dmtimer_systimer_check_counter32k(void) 127*52762fbdSTony Lindgren { 128*52762fbdSTony Lindgren struct device_node *np; 129*52762fbdSTony Lindgren 130*52762fbdSTony Lindgren if (counter_32k) 131*52762fbdSTony Lindgren return; 132*52762fbdSTony Lindgren 133*52762fbdSTony Lindgren np = of_find_matching_node(NULL, counter_match_table); 134*52762fbdSTony Lindgren if (!np) { 135*52762fbdSTony Lindgren counter_32k = -ENODEV; 136*52762fbdSTony Lindgren 137*52762fbdSTony Lindgren return; 138*52762fbdSTony Lindgren } 139*52762fbdSTony Lindgren 140*52762fbdSTony Lindgren if (of_device_is_available(np)) 141*52762fbdSTony Lindgren counter_32k = 1; 142*52762fbdSTony Lindgren else 143*52762fbdSTony Lindgren counter_32k = -ENODEV; 144*52762fbdSTony Lindgren 145*52762fbdSTony Lindgren of_node_put(np); 146*52762fbdSTony Lindgren } 147*52762fbdSTony Lindgren 148*52762fbdSTony Lindgren static const struct of_device_id dmtimer_match_table[] = { 149*52762fbdSTony Lindgren { .compatible = "ti,omap2420-timer", }, 150*52762fbdSTony Lindgren { .compatible = "ti,omap3430-timer", }, 151*52762fbdSTony Lindgren { .compatible = "ti,omap4430-timer", }, 152*52762fbdSTony Lindgren { .compatible = "ti,omap5430-timer", }, 153*52762fbdSTony Lindgren { .compatible = "ti,am335x-timer", }, 154*52762fbdSTony Lindgren { .compatible = "ti,am335x-timer-1ms", }, 155*52762fbdSTony Lindgren { .compatible = "ti,dm814-timer", }, 156*52762fbdSTony Lindgren { .compatible = "ti,dm816-timer", }, 157*52762fbdSTony Lindgren { /* Sentinel */ }, 158*52762fbdSTony Lindgren }; 159*52762fbdSTony Lindgren 160*52762fbdSTony Lindgren /* 161*52762fbdSTony Lindgren * Checks that system timers are configured to not reset and idle during 162*52762fbdSTony Lindgren * the generic timer-ti-dm device driver probe. And that the system timer 163*52762fbdSTony Lindgren * source clocks are properly configured. Also, let's not hog any DSP and 164*52762fbdSTony Lindgren * PWM capable timers unnecessarily as system timers. 165*52762fbdSTony Lindgren */ 166*52762fbdSTony Lindgren static bool __init dmtimer_is_preferred(struct device_node *np) 167*52762fbdSTony Lindgren { 168*52762fbdSTony Lindgren if (!of_device_is_available(np)) 169*52762fbdSTony Lindgren return false; 170*52762fbdSTony Lindgren 171*52762fbdSTony Lindgren if (!of_property_read_bool(np->parent, 172*52762fbdSTony Lindgren "ti,no-reset-on-init")) 173*52762fbdSTony Lindgren return false; 174*52762fbdSTony Lindgren 175*52762fbdSTony Lindgren if (!of_property_read_bool(np->parent, "ti,no-idle")) 176*52762fbdSTony Lindgren return false; 177*52762fbdSTony Lindgren 178*52762fbdSTony Lindgren /* Secure gptimer12 is always clocked with a fixed source */ 179*52762fbdSTony Lindgren if (!of_property_read_bool(np, "ti,timer-secure")) { 180*52762fbdSTony Lindgren if (!of_property_read_bool(np, "assigned-clocks")) 181*52762fbdSTony Lindgren return false; 182*52762fbdSTony Lindgren 183*52762fbdSTony Lindgren if (!of_property_read_bool(np, "assigned-clock-parents")) 184*52762fbdSTony Lindgren return false; 185*52762fbdSTony Lindgren } 186*52762fbdSTony Lindgren 187*52762fbdSTony Lindgren if (of_property_read_bool(np, "ti,timer-dsp")) 188*52762fbdSTony Lindgren return false; 189*52762fbdSTony Lindgren 190*52762fbdSTony Lindgren if (of_property_read_bool(np, "ti,timer-pwm")) 191*52762fbdSTony Lindgren return false; 192*52762fbdSTony Lindgren 193*52762fbdSTony Lindgren return true; 194*52762fbdSTony Lindgren } 195*52762fbdSTony Lindgren 196*52762fbdSTony Lindgren /* 197*52762fbdSTony Lindgren * Finds the first available usable always-on timer, and assigns it to either 198*52762fbdSTony Lindgren * clockevent or clocksource depending if the counter_32k is available on the 199*52762fbdSTony Lindgren * SoC or not. 200*52762fbdSTony Lindgren * 201*52762fbdSTony Lindgren * Some omap3 boards with unreliable oscillator must not use the counter_32k 202*52762fbdSTony Lindgren * or dmtimer1 with 32 KiHz source. Additionally, the boards with unreliable 203*52762fbdSTony Lindgren * oscillator should really set counter_32k as disabled, and delete dmtimer1 204*52762fbdSTony Lindgren * ti,always-on property, but let's not count on it. For these quirky cases, 205*52762fbdSTony Lindgren * we prefer using the always-on secure dmtimer12 with the internal 32 KiHz 206*52762fbdSTony Lindgren * clock as the clocksource, and any available dmtimer as clockevent. 207*52762fbdSTony Lindgren * 208*52762fbdSTony Lindgren * For am437x, we are using am335x style dmtimer clocksource. It is unclear 209*52762fbdSTony Lindgren * if this quirk handling is really needed, but let's change it separately 210*52762fbdSTony Lindgren * based on testing as it might cause side effects. 211*52762fbdSTony Lindgren */ 212*52762fbdSTony Lindgren static void __init dmtimer_systimer_assign_alwon(void) 213*52762fbdSTony Lindgren { 214*52762fbdSTony Lindgren struct device_node *np; 215*52762fbdSTony Lindgren u32 pa = 0; 216*52762fbdSTony Lindgren bool quirk_unreliable_oscillator = false; 217*52762fbdSTony Lindgren 218*52762fbdSTony Lindgren /* Quirk unreliable 32 KiHz oscillator with incomplete dts */ 219*52762fbdSTony Lindgren if (of_machine_is_compatible("ti,omap3-beagle") || 220*52762fbdSTony Lindgren of_machine_is_compatible("timll,omap3-devkit8000")) { 221*52762fbdSTony Lindgren quirk_unreliable_oscillator = true; 222*52762fbdSTony Lindgren counter_32k = -ENODEV; 223*52762fbdSTony Lindgren } 224*52762fbdSTony Lindgren 225*52762fbdSTony Lindgren /* Quirk am437x using am335x style dmtimer clocksource */ 226*52762fbdSTony Lindgren if (of_machine_is_compatible("ti,am43")) 227*52762fbdSTony Lindgren counter_32k = -ENODEV; 228*52762fbdSTony Lindgren 229*52762fbdSTony Lindgren for_each_matching_node(np, dmtimer_match_table) { 230*52762fbdSTony Lindgren if (!dmtimer_is_preferred(np)) 231*52762fbdSTony Lindgren continue; 232*52762fbdSTony Lindgren 233*52762fbdSTony Lindgren if (of_property_read_bool(np, "ti,timer-alwon")) { 234*52762fbdSTony Lindgren const __be32 *addr; 235*52762fbdSTony Lindgren 236*52762fbdSTony Lindgren addr = of_get_address(np, 0, NULL, NULL); 237*52762fbdSTony Lindgren pa = of_translate_address(np, addr); 238*52762fbdSTony Lindgren if (pa) { 239*52762fbdSTony Lindgren /* Quirky omap3 boards must use dmtimer12 */ 240*52762fbdSTony Lindgren if (quirk_unreliable_oscillator && 241*52762fbdSTony Lindgren pa == 0x48318000) 242*52762fbdSTony Lindgren continue; 243*52762fbdSTony Lindgren 244*52762fbdSTony Lindgren of_node_put(np); 245*52762fbdSTony Lindgren break; 246*52762fbdSTony Lindgren } 247*52762fbdSTony Lindgren } 248*52762fbdSTony Lindgren } 249*52762fbdSTony Lindgren 250*52762fbdSTony Lindgren /* Usually no need for dmtimer clocksource if we have counter32 */ 251*52762fbdSTony Lindgren if (counter_32k >= 0) { 252*52762fbdSTony Lindgren clockevent = pa; 253*52762fbdSTony Lindgren clocksource = 0; 254*52762fbdSTony Lindgren } else { 255*52762fbdSTony Lindgren clocksource = pa; 256*52762fbdSTony Lindgren clockevent = DMTIMER_INST_DONT_CARE; 257*52762fbdSTony Lindgren } 258*52762fbdSTony Lindgren } 259*52762fbdSTony Lindgren 260*52762fbdSTony Lindgren /* Finds the first usable dmtimer, used for the don't care case */ 261*52762fbdSTony Lindgren static u32 __init dmtimer_systimer_find_first_available(void) 262*52762fbdSTony Lindgren { 263*52762fbdSTony Lindgren struct device_node *np; 264*52762fbdSTony Lindgren const __be32 *addr; 265*52762fbdSTony Lindgren u32 pa = 0; 266*52762fbdSTony Lindgren 267*52762fbdSTony Lindgren for_each_matching_node(np, dmtimer_match_table) { 268*52762fbdSTony Lindgren if (!dmtimer_is_preferred(np)) 269*52762fbdSTony Lindgren continue; 270*52762fbdSTony Lindgren 271*52762fbdSTony Lindgren addr = of_get_address(np, 0, NULL, NULL); 272*52762fbdSTony Lindgren pa = of_translate_address(np, addr); 273*52762fbdSTony Lindgren if (pa) { 274*52762fbdSTony Lindgren if (pa == clocksource || pa == clockevent) { 275*52762fbdSTony Lindgren pa = 0; 276*52762fbdSTony Lindgren continue; 277*52762fbdSTony Lindgren } 278*52762fbdSTony Lindgren 279*52762fbdSTony Lindgren of_node_put(np); 280*52762fbdSTony Lindgren break; 281*52762fbdSTony Lindgren } 282*52762fbdSTony Lindgren } 283*52762fbdSTony Lindgren 284*52762fbdSTony Lindgren return pa; 285*52762fbdSTony Lindgren } 286*52762fbdSTony Lindgren 287*52762fbdSTony Lindgren /* Selects the best clocksource and clockevent to use */ 288*52762fbdSTony Lindgren static void __init dmtimer_systimer_select_best(void) 289*52762fbdSTony Lindgren { 290*52762fbdSTony Lindgren dmtimer_systimer_check_counter32k(); 291*52762fbdSTony Lindgren dmtimer_systimer_assign_alwon(); 292*52762fbdSTony Lindgren 293*52762fbdSTony Lindgren if (clockevent == DMTIMER_INST_DONT_CARE) 294*52762fbdSTony Lindgren clockevent = dmtimer_systimer_find_first_available(); 295*52762fbdSTony Lindgren 296*52762fbdSTony Lindgren pr_debug("%s: counter_32k: %i clocksource: %08x clockevent: %08x\n", 297*52762fbdSTony Lindgren __func__, counter_32k, clocksource, clockevent); 298*52762fbdSTony Lindgren } 299*52762fbdSTony Lindgren 300*52762fbdSTony Lindgren /* Interface clocks are only available on some SoCs variants */ 301*52762fbdSTony Lindgren static int __init dmtimer_systimer_init_clock(struct device_node *np, 302*52762fbdSTony Lindgren const char *name, 303*52762fbdSTony Lindgren unsigned long *rate) 304*52762fbdSTony Lindgren { 305*52762fbdSTony Lindgren struct clk *clock; 306*52762fbdSTony Lindgren unsigned long r; 307*52762fbdSTony Lindgren int error; 308*52762fbdSTony Lindgren 309*52762fbdSTony Lindgren clock = of_clk_get_by_name(np, name); 310*52762fbdSTony Lindgren if ((PTR_ERR(clock) == -EINVAL) && !strncmp(name, "ick", 3)) 311*52762fbdSTony Lindgren return 0; 312*52762fbdSTony Lindgren else if (IS_ERR(clock)) 313*52762fbdSTony Lindgren return PTR_ERR(clock); 314*52762fbdSTony Lindgren 315*52762fbdSTony Lindgren error = clk_prepare_enable(clock); 316*52762fbdSTony Lindgren if (error) 317*52762fbdSTony Lindgren return error; 318*52762fbdSTony Lindgren 319*52762fbdSTony Lindgren r = clk_get_rate(clock); 320*52762fbdSTony Lindgren if (!r) 321*52762fbdSTony Lindgren return -ENODEV; 322*52762fbdSTony Lindgren 323*52762fbdSTony Lindgren *rate = r; 324*52762fbdSTony Lindgren 325*52762fbdSTony Lindgren return 0; 326*52762fbdSTony Lindgren } 327*52762fbdSTony Lindgren 328*52762fbdSTony Lindgren static void dmtimer_systimer_enable(struct dmtimer_systimer *t) 329*52762fbdSTony Lindgren { 330*52762fbdSTony Lindgren u32 val; 331*52762fbdSTony Lindgren 332*52762fbdSTony Lindgren if (dmtimer_systimer_revision1(t)) 333*52762fbdSTony Lindgren val = DMTIMER_TYPE1_ENABLE; 334*52762fbdSTony Lindgren else 335*52762fbdSTony Lindgren val = DMTIMER_TYPE2_ENABLE; 336*52762fbdSTony Lindgren 337*52762fbdSTony Lindgren writel_relaxed(val, t->base + t->sysc); 338*52762fbdSTony Lindgren } 339*52762fbdSTony Lindgren 340*52762fbdSTony Lindgren static void dmtimer_systimer_disable(struct dmtimer_systimer *t) 341*52762fbdSTony Lindgren { 342*52762fbdSTony Lindgren writel_relaxed(0, t->base + t->sysc); 343*52762fbdSTony Lindgren } 344*52762fbdSTony Lindgren 345*52762fbdSTony Lindgren static int __init dmtimer_systimer_setup(struct device_node *np, 346*52762fbdSTony Lindgren struct dmtimer_systimer *t) 347*52762fbdSTony Lindgren { 348*52762fbdSTony Lindgren unsigned long rate; 349*52762fbdSTony Lindgren u8 regbase; 350*52762fbdSTony Lindgren int error; 351*52762fbdSTony Lindgren 352*52762fbdSTony Lindgren if (!of_device_is_compatible(np->parent, "ti,sysc")) 353*52762fbdSTony Lindgren return -EINVAL; 354*52762fbdSTony Lindgren 355*52762fbdSTony Lindgren t->base = of_iomap(np, 0); 356*52762fbdSTony Lindgren if (!t->base) 357*52762fbdSTony Lindgren return -ENXIO; 358*52762fbdSTony Lindgren 359*52762fbdSTony Lindgren /* 360*52762fbdSTony Lindgren * Enable optional assigned-clock-parents configured at the timer 361*52762fbdSTony Lindgren * node level. For regular device drivers, this is done automatically 362*52762fbdSTony Lindgren * by bus related code such as platform_drv_probe(). 363*52762fbdSTony Lindgren */ 364*52762fbdSTony Lindgren error = of_clk_set_defaults(np, false); 365*52762fbdSTony Lindgren if (error < 0) 366*52762fbdSTony Lindgren pr_err("%s: clock source init failed: %i\n", __func__, error); 367*52762fbdSTony Lindgren 368*52762fbdSTony Lindgren /* For ti-sysc, we have timer clocks at the parent module level */ 369*52762fbdSTony Lindgren error = dmtimer_systimer_init_clock(np->parent, "fck", &rate); 370*52762fbdSTony Lindgren if (error) 371*52762fbdSTony Lindgren goto err_unmap; 372*52762fbdSTony Lindgren 373*52762fbdSTony Lindgren t->rate = rate; 374*52762fbdSTony Lindgren 375*52762fbdSTony Lindgren error = dmtimer_systimer_init_clock(np->parent, "ick", &rate); 376*52762fbdSTony Lindgren if (error) 377*52762fbdSTony Lindgren goto err_unmap; 378*52762fbdSTony Lindgren 379*52762fbdSTony Lindgren if (dmtimer_systimer_revision1(t)) { 380*52762fbdSTony Lindgren t->irq_stat = OMAP_TIMER_V1_STAT_OFFSET; 381*52762fbdSTony Lindgren t->irq_ena = OMAP_TIMER_V1_INT_EN_OFFSET; 382*52762fbdSTony Lindgren t->pend = _OMAP_TIMER_WRITE_PEND_OFFSET; 383*52762fbdSTony Lindgren regbase = 0; 384*52762fbdSTony Lindgren } else { 385*52762fbdSTony Lindgren t->irq_stat = OMAP_TIMER_V2_IRQSTATUS; 386*52762fbdSTony Lindgren t->irq_ena = OMAP_TIMER_V2_IRQENABLE_SET; 387*52762fbdSTony Lindgren regbase = OMAP_TIMER_V2_FUNC_OFFSET; 388*52762fbdSTony Lindgren t->pend = regbase + _OMAP_TIMER_WRITE_PEND_OFFSET; 389*52762fbdSTony Lindgren } 390*52762fbdSTony Lindgren 391*52762fbdSTony Lindgren t->sysc = OMAP_TIMER_OCP_CFG_OFFSET; 392*52762fbdSTony Lindgren t->load = regbase + _OMAP_TIMER_LOAD_OFFSET; 393*52762fbdSTony Lindgren t->counter = regbase + _OMAP_TIMER_COUNTER_OFFSET; 394*52762fbdSTony Lindgren t->ctrl = regbase + _OMAP_TIMER_CTRL_OFFSET; 395*52762fbdSTony Lindgren t->wakeup = regbase + _OMAP_TIMER_WAKEUP_EN_OFFSET; 396*52762fbdSTony Lindgren t->ifctrl = regbase + _OMAP_TIMER_IF_CTRL_OFFSET; 397*52762fbdSTony Lindgren 398*52762fbdSTony Lindgren dmtimer_systimer_enable(t); 399*52762fbdSTony Lindgren dmtimer_systimer_reset(t); 400*52762fbdSTony Lindgren pr_debug("dmtimer rev %08x sysc %08x\n", readl_relaxed(t->base), 401*52762fbdSTony Lindgren readl_relaxed(t->base + t->sysc)); 402*52762fbdSTony Lindgren 403*52762fbdSTony Lindgren return 0; 404*52762fbdSTony Lindgren 405*52762fbdSTony Lindgren err_unmap: 406*52762fbdSTony Lindgren iounmap(t->base); 407*52762fbdSTony Lindgren 408*52762fbdSTony Lindgren return error; 409*52762fbdSTony Lindgren } 410*52762fbdSTony Lindgren 411*52762fbdSTony Lindgren /* Clockevent */ 412*52762fbdSTony Lindgren static struct dmtimer_clockevent * 413*52762fbdSTony Lindgren to_dmtimer_clockevent(struct clock_event_device *clockevent) 414*52762fbdSTony Lindgren { 415*52762fbdSTony Lindgren return container_of(clockevent, struct dmtimer_clockevent, dev); 416*52762fbdSTony Lindgren } 417*52762fbdSTony Lindgren 418*52762fbdSTony Lindgren static irqreturn_t dmtimer_clockevent_interrupt(int irq, void *data) 419*52762fbdSTony Lindgren { 420*52762fbdSTony Lindgren struct dmtimer_clockevent *clkevt = data; 421*52762fbdSTony Lindgren struct dmtimer_systimer *t = &clkevt->t; 422*52762fbdSTony Lindgren 423*52762fbdSTony Lindgren writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_stat); 424*52762fbdSTony Lindgren clkevt->dev.event_handler(&clkevt->dev); 425*52762fbdSTony Lindgren 426*52762fbdSTony Lindgren return IRQ_HANDLED; 427*52762fbdSTony Lindgren } 428*52762fbdSTony Lindgren 429*52762fbdSTony Lindgren static int dmtimer_set_next_event(unsigned long cycles, 430*52762fbdSTony Lindgren struct clock_event_device *evt) 431*52762fbdSTony Lindgren { 432*52762fbdSTony Lindgren struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); 433*52762fbdSTony Lindgren struct dmtimer_systimer *t = &clkevt->t; 434*52762fbdSTony Lindgren void __iomem *pend = t->base + t->pend; 435*52762fbdSTony Lindgren 436*52762fbdSTony Lindgren writel_relaxed(0xffffffff - cycles, t->base + t->counter); 437*52762fbdSTony Lindgren while (readl_relaxed(pend) & WP_TCRR) 438*52762fbdSTony Lindgren cpu_relax(); 439*52762fbdSTony Lindgren 440*52762fbdSTony Lindgren writel_relaxed(OMAP_TIMER_CTRL_ST, t->base + t->ctrl); 441*52762fbdSTony Lindgren while (readl_relaxed(pend) & WP_TCLR) 442*52762fbdSTony Lindgren cpu_relax(); 443*52762fbdSTony Lindgren 444*52762fbdSTony Lindgren return 0; 445*52762fbdSTony Lindgren } 446*52762fbdSTony Lindgren 447*52762fbdSTony Lindgren static int dmtimer_clockevent_shutdown(struct clock_event_device *evt) 448*52762fbdSTony Lindgren { 449*52762fbdSTony Lindgren struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); 450*52762fbdSTony Lindgren struct dmtimer_systimer *t = &clkevt->t; 451*52762fbdSTony Lindgren void __iomem *ctrl = t->base + t->ctrl; 452*52762fbdSTony Lindgren u32 l; 453*52762fbdSTony Lindgren 454*52762fbdSTony Lindgren l = readl_relaxed(ctrl); 455*52762fbdSTony Lindgren if (l & OMAP_TIMER_CTRL_ST) { 456*52762fbdSTony Lindgren l &= ~BIT(0); 457*52762fbdSTony Lindgren writel_relaxed(l, ctrl); 458*52762fbdSTony Lindgren /* Flush posted write */ 459*52762fbdSTony Lindgren l = readl_relaxed(ctrl); 460*52762fbdSTony Lindgren /* Wait for functional clock period x 3.5 */ 461*52762fbdSTony Lindgren udelay(3500000 / t->rate + 1); 462*52762fbdSTony Lindgren } 463*52762fbdSTony Lindgren writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_stat); 464*52762fbdSTony Lindgren 465*52762fbdSTony Lindgren return 0; 466*52762fbdSTony Lindgren } 467*52762fbdSTony Lindgren 468*52762fbdSTony Lindgren static int dmtimer_set_periodic(struct clock_event_device *evt) 469*52762fbdSTony Lindgren { 470*52762fbdSTony Lindgren struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); 471*52762fbdSTony Lindgren struct dmtimer_systimer *t = &clkevt->t; 472*52762fbdSTony Lindgren void __iomem *pend = t->base + t->pend; 473*52762fbdSTony Lindgren 474*52762fbdSTony Lindgren dmtimer_clockevent_shutdown(evt); 475*52762fbdSTony Lindgren 476*52762fbdSTony Lindgren /* Looks like we need to first set the load value separately */ 477*52762fbdSTony Lindgren writel_relaxed(clkevt->period, t->base + t->load); 478*52762fbdSTony Lindgren while (readl_relaxed(pend) & WP_TLDR) 479*52762fbdSTony Lindgren cpu_relax(); 480*52762fbdSTony Lindgren 481*52762fbdSTony Lindgren writel_relaxed(clkevt->period, t->base + t->counter); 482*52762fbdSTony Lindgren while (readl_relaxed(pend) & WP_TCRR) 483*52762fbdSTony Lindgren cpu_relax(); 484*52762fbdSTony Lindgren 485*52762fbdSTony Lindgren writel_relaxed(OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST, 486*52762fbdSTony Lindgren t->base + t->ctrl); 487*52762fbdSTony Lindgren while (readl_relaxed(pend) & WP_TCLR) 488*52762fbdSTony Lindgren cpu_relax(); 489*52762fbdSTony Lindgren 490*52762fbdSTony Lindgren return 0; 491*52762fbdSTony Lindgren } 492*52762fbdSTony Lindgren 493*52762fbdSTony Lindgren static void omap_clockevent_idle(struct clock_event_device *evt) 494*52762fbdSTony Lindgren { 495*52762fbdSTony Lindgren struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); 496*52762fbdSTony Lindgren struct dmtimer_systimer *t = &clkevt->t; 497*52762fbdSTony Lindgren 498*52762fbdSTony Lindgren dmtimer_systimer_disable(t); 499*52762fbdSTony Lindgren } 500*52762fbdSTony Lindgren 501*52762fbdSTony Lindgren static void omap_clockevent_unidle(struct clock_event_device *evt) 502*52762fbdSTony Lindgren { 503*52762fbdSTony Lindgren struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); 504*52762fbdSTony Lindgren struct dmtimer_systimer *t = &clkevt->t; 505*52762fbdSTony Lindgren 506*52762fbdSTony Lindgren dmtimer_systimer_enable(t); 507*52762fbdSTony Lindgren writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_ena); 508*52762fbdSTony Lindgren writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->wakeup); 509*52762fbdSTony Lindgren } 510*52762fbdSTony Lindgren 511*52762fbdSTony Lindgren static int __init dmtimer_clockevent_init(struct device_node *np) 512*52762fbdSTony Lindgren { 513*52762fbdSTony Lindgren struct dmtimer_clockevent *clkevt; 514*52762fbdSTony Lindgren struct clock_event_device *dev; 515*52762fbdSTony Lindgren struct dmtimer_systimer *t; 516*52762fbdSTony Lindgren int error; 517*52762fbdSTony Lindgren u32 pa; 518*52762fbdSTony Lindgren 519*52762fbdSTony Lindgren clkevt = kzalloc(sizeof(*clkevt), GFP_KERNEL); 520*52762fbdSTony Lindgren if (!clkevt) 521*52762fbdSTony Lindgren return -ENOMEM; 522*52762fbdSTony Lindgren 523*52762fbdSTony Lindgren t = &clkevt->t; 524*52762fbdSTony Lindgren dev = &clkevt->dev; 525*52762fbdSTony Lindgren 526*52762fbdSTony Lindgren /* 527*52762fbdSTony Lindgren * We mostly use cpuidle_coupled with ARM local timers for runtime, 528*52762fbdSTony Lindgren * so there's probably no use for CLOCK_EVT_FEAT_DYNIRQ here. 529*52762fbdSTony Lindgren */ 530*52762fbdSTony Lindgren dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 531*52762fbdSTony Lindgren dev->rating = 300; 532*52762fbdSTony Lindgren dev->set_next_event = dmtimer_set_next_event; 533*52762fbdSTony Lindgren dev->set_state_shutdown = dmtimer_clockevent_shutdown; 534*52762fbdSTony Lindgren dev->set_state_periodic = dmtimer_set_periodic; 535*52762fbdSTony Lindgren dev->set_state_oneshot = dmtimer_clockevent_shutdown; 536*52762fbdSTony Lindgren dev->tick_resume = dmtimer_clockevent_shutdown; 537*52762fbdSTony Lindgren dev->cpumask = cpu_possible_mask; 538*52762fbdSTony Lindgren 539*52762fbdSTony Lindgren dev->irq = irq_of_parse_and_map(np, 0); 540*52762fbdSTony Lindgren if (!dev->irq) { 541*52762fbdSTony Lindgren error = -ENXIO; 542*52762fbdSTony Lindgren goto err_out_free; 543*52762fbdSTony Lindgren } 544*52762fbdSTony Lindgren 545*52762fbdSTony Lindgren error = dmtimer_systimer_setup(np, &clkevt->t); 546*52762fbdSTony Lindgren if (error) 547*52762fbdSTony Lindgren goto err_out_free; 548*52762fbdSTony Lindgren 549*52762fbdSTony Lindgren clkevt->period = 0xffffffff - DIV_ROUND_CLOSEST(t->rate, HZ); 550*52762fbdSTony Lindgren 551*52762fbdSTony Lindgren /* 552*52762fbdSTony Lindgren * For clock-event timers we never read the timer counter and 553*52762fbdSTony Lindgren * so we are not impacted by errata i103 and i767. Therefore, 554*52762fbdSTony Lindgren * we can safely ignore this errata for clock-event timers. 555*52762fbdSTony Lindgren */ 556*52762fbdSTony Lindgren writel_relaxed(OMAP_TIMER_CTRL_POSTED, t->base + t->ifctrl); 557*52762fbdSTony Lindgren 558*52762fbdSTony Lindgren error = request_irq(dev->irq, dmtimer_clockevent_interrupt, 559*52762fbdSTony Lindgren IRQF_TIMER, "clockevent", clkevt); 560*52762fbdSTony Lindgren if (error) 561*52762fbdSTony Lindgren goto err_out_unmap; 562*52762fbdSTony Lindgren 563*52762fbdSTony Lindgren writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_ena); 564*52762fbdSTony Lindgren writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->wakeup); 565*52762fbdSTony Lindgren 566*52762fbdSTony Lindgren pa = of_translate_address(np, of_get_address(np, 0, NULL, NULL)); 567*52762fbdSTony Lindgren pr_info("TI gptimer clockevent: %s%lu Hz at %pOF\n", 568*52762fbdSTony Lindgren of_find_property(np, "ti,timer-alwon", NULL) ? 569*52762fbdSTony Lindgren "always-on " : "", t->rate, np->parent); 570*52762fbdSTony Lindgren 571*52762fbdSTony Lindgren clockevents_config_and_register(dev, t->rate, 572*52762fbdSTony Lindgren 3, /* Timer internal resynch latency */ 573*52762fbdSTony Lindgren 0xffffffff); 574*52762fbdSTony Lindgren 575*52762fbdSTony Lindgren if (of_device_is_compatible(np, "ti,am33xx") || 576*52762fbdSTony Lindgren of_device_is_compatible(np, "ti,am43")) { 577*52762fbdSTony Lindgren dev->suspend = omap_clockevent_idle; 578*52762fbdSTony Lindgren dev->resume = omap_clockevent_unidle; 579*52762fbdSTony Lindgren } 580*52762fbdSTony Lindgren 581*52762fbdSTony Lindgren return 0; 582*52762fbdSTony Lindgren 583*52762fbdSTony Lindgren err_out_unmap: 584*52762fbdSTony Lindgren iounmap(t->base); 585*52762fbdSTony Lindgren 586*52762fbdSTony Lindgren err_out_free: 587*52762fbdSTony Lindgren kfree(clkevt); 588*52762fbdSTony Lindgren 589*52762fbdSTony Lindgren return error; 590*52762fbdSTony Lindgren } 591*52762fbdSTony Lindgren 592*52762fbdSTony Lindgren /* Clocksource */ 593*52762fbdSTony Lindgren static struct dmtimer_clocksource * 594*52762fbdSTony Lindgren to_dmtimer_clocksource(struct clocksource *cs) 595*52762fbdSTony Lindgren { 596*52762fbdSTony Lindgren return container_of(cs, struct dmtimer_clocksource, dev); 597*52762fbdSTony Lindgren } 598*52762fbdSTony Lindgren 599*52762fbdSTony Lindgren static u64 dmtimer_clocksource_read_cycles(struct clocksource *cs) 600*52762fbdSTony Lindgren { 601*52762fbdSTony Lindgren struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs); 602*52762fbdSTony Lindgren struct dmtimer_systimer *t = &clksrc->t; 603*52762fbdSTony Lindgren 604*52762fbdSTony Lindgren return (u64)readl_relaxed(t->base + t->counter); 605*52762fbdSTony Lindgren } 606*52762fbdSTony Lindgren 607*52762fbdSTony Lindgren static void __iomem *dmtimer_sched_clock_counter; 608*52762fbdSTony Lindgren 609*52762fbdSTony Lindgren static u64 notrace dmtimer_read_sched_clock(void) 610*52762fbdSTony Lindgren { 611*52762fbdSTony Lindgren return readl_relaxed(dmtimer_sched_clock_counter); 612*52762fbdSTony Lindgren } 613*52762fbdSTony Lindgren 614*52762fbdSTony Lindgren static void dmtimer_clocksource_suspend(struct clocksource *cs) 615*52762fbdSTony Lindgren { 616*52762fbdSTony Lindgren struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs); 617*52762fbdSTony Lindgren struct dmtimer_systimer *t = &clksrc->t; 618*52762fbdSTony Lindgren 619*52762fbdSTony Lindgren clksrc->loadval = readl_relaxed(t->base + t->counter); 620*52762fbdSTony Lindgren dmtimer_systimer_disable(t); 621*52762fbdSTony Lindgren } 622*52762fbdSTony Lindgren 623*52762fbdSTony Lindgren static void dmtimer_clocksource_resume(struct clocksource *cs) 624*52762fbdSTony Lindgren { 625*52762fbdSTony Lindgren struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs); 626*52762fbdSTony Lindgren struct dmtimer_systimer *t = &clksrc->t; 627*52762fbdSTony Lindgren 628*52762fbdSTony Lindgren dmtimer_systimer_enable(t); 629*52762fbdSTony Lindgren writel_relaxed(clksrc->loadval, t->base + t->counter); 630*52762fbdSTony Lindgren writel_relaxed(OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 631*52762fbdSTony Lindgren t->base + t->ctrl); 632*52762fbdSTony Lindgren } 633*52762fbdSTony Lindgren 634*52762fbdSTony Lindgren static int __init dmtimer_clocksource_init(struct device_node *np) 635*52762fbdSTony Lindgren { 636*52762fbdSTony Lindgren struct dmtimer_clocksource *clksrc; 637*52762fbdSTony Lindgren struct dmtimer_systimer *t; 638*52762fbdSTony Lindgren struct clocksource *dev; 639*52762fbdSTony Lindgren int error; 640*52762fbdSTony Lindgren u32 pa; 641*52762fbdSTony Lindgren 642*52762fbdSTony Lindgren clksrc = kzalloc(sizeof(*clksrc), GFP_KERNEL); 643*52762fbdSTony Lindgren if (!clksrc) 644*52762fbdSTony Lindgren return -ENOMEM; 645*52762fbdSTony Lindgren 646*52762fbdSTony Lindgren dev = &clksrc->dev; 647*52762fbdSTony Lindgren t = &clksrc->t; 648*52762fbdSTony Lindgren 649*52762fbdSTony Lindgren error = dmtimer_systimer_setup(np, t); 650*52762fbdSTony Lindgren if (error) 651*52762fbdSTony Lindgren goto err_out_free; 652*52762fbdSTony Lindgren 653*52762fbdSTony Lindgren dev->name = "dmtimer"; 654*52762fbdSTony Lindgren dev->rating = 300; 655*52762fbdSTony Lindgren dev->read = dmtimer_clocksource_read_cycles; 656*52762fbdSTony Lindgren dev->mask = CLOCKSOURCE_MASK(32); 657*52762fbdSTony Lindgren dev->flags = CLOCK_SOURCE_IS_CONTINUOUS; 658*52762fbdSTony Lindgren 659*52762fbdSTony Lindgren if (of_device_is_compatible(np, "ti,am33xx") || 660*52762fbdSTony Lindgren of_device_is_compatible(np, "ti,am43")) { 661*52762fbdSTony Lindgren dev->suspend = dmtimer_clocksource_suspend; 662*52762fbdSTony Lindgren dev->resume = dmtimer_clocksource_resume; 663*52762fbdSTony Lindgren } 664*52762fbdSTony Lindgren 665*52762fbdSTony Lindgren writel_relaxed(0, t->base + t->counter); 666*52762fbdSTony Lindgren writel_relaxed(OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 667*52762fbdSTony Lindgren t->base + t->ctrl); 668*52762fbdSTony Lindgren 669*52762fbdSTony Lindgren pa = of_translate_address(np, of_get_address(np, 0, NULL, NULL)); 670*52762fbdSTony Lindgren pr_info("TI gptimer clocksource: %s%pOF\n", 671*52762fbdSTony Lindgren of_find_property(np, "ti,timer-alwon", NULL) ? 672*52762fbdSTony Lindgren "always-on " : "", np->parent); 673*52762fbdSTony Lindgren 674*52762fbdSTony Lindgren if (!dmtimer_sched_clock_counter) { 675*52762fbdSTony Lindgren dmtimer_sched_clock_counter = t->base + t->counter; 676*52762fbdSTony Lindgren sched_clock_register(dmtimer_read_sched_clock, 32, t->rate); 677*52762fbdSTony Lindgren } 678*52762fbdSTony Lindgren 679*52762fbdSTony Lindgren if (clocksource_register_hz(dev, t->rate)) 680*52762fbdSTony Lindgren pr_err("Could not register clocksource %pOF\n", np); 681*52762fbdSTony Lindgren 682*52762fbdSTony Lindgren return 0; 683*52762fbdSTony Lindgren 684*52762fbdSTony Lindgren err_out_free: 685*52762fbdSTony Lindgren kfree(clksrc); 686*52762fbdSTony Lindgren 687*52762fbdSTony Lindgren return -ENODEV; 688*52762fbdSTony Lindgren } 689*52762fbdSTony Lindgren 690*52762fbdSTony Lindgren /* 691*52762fbdSTony Lindgren * To detect between a clocksource and clockevent, we assume the device tree 692*52762fbdSTony Lindgren * has no interrupts configured for a clocksource timer. 693*52762fbdSTony Lindgren */ 694*52762fbdSTony Lindgren static int __init dmtimer_systimer_init(struct device_node *np) 695*52762fbdSTony Lindgren { 696*52762fbdSTony Lindgren const __be32 *addr; 697*52762fbdSTony Lindgren u32 pa; 698*52762fbdSTony Lindgren 699*52762fbdSTony Lindgren /* One time init for the preferred timer configuration */ 700*52762fbdSTony Lindgren if (!clocksource && !clockevent) 701*52762fbdSTony Lindgren dmtimer_systimer_select_best(); 702*52762fbdSTony Lindgren 703*52762fbdSTony Lindgren if (!clocksource && !clockevent) { 704*52762fbdSTony Lindgren pr_err("%s: unable to detectt system timers, update dtb?\n", 705*52762fbdSTony Lindgren __func__); 706*52762fbdSTony Lindgren 707*52762fbdSTony Lindgren return -EINVAL; 708*52762fbdSTony Lindgren } 709*52762fbdSTony Lindgren 710*52762fbdSTony Lindgren addr = of_get_address(np, 0, NULL, NULL); 711*52762fbdSTony Lindgren pa = of_translate_address(np, addr); 712*52762fbdSTony Lindgren if (!pa) 713*52762fbdSTony Lindgren return -EINVAL; 714*52762fbdSTony Lindgren 715*52762fbdSTony Lindgren if (counter_32k <= 0 && clocksource == pa) 716*52762fbdSTony Lindgren return dmtimer_clocksource_init(np); 717*52762fbdSTony Lindgren 718*52762fbdSTony Lindgren if (clockevent == pa) 719*52762fbdSTony Lindgren return dmtimer_clockevent_init(np); 720*52762fbdSTony Lindgren 721*52762fbdSTony Lindgren return 0; 722*52762fbdSTony Lindgren } 723*52762fbdSTony Lindgren 724*52762fbdSTony Lindgren TIMER_OF_DECLARE(systimer_omap2, "ti,omap2420-timer", dmtimer_systimer_init); 725*52762fbdSTony Lindgren TIMER_OF_DECLARE(systimer_omap3, "ti,omap3430-timer", dmtimer_systimer_init); 726*52762fbdSTony Lindgren TIMER_OF_DECLARE(systimer_omap4, "ti,omap4430-timer", dmtimer_systimer_init); 727*52762fbdSTony Lindgren TIMER_OF_DECLARE(systimer_omap5, "ti,omap5430-timer", dmtimer_systimer_init); 728*52762fbdSTony Lindgren TIMER_OF_DECLARE(systimer_am33x, "ti,am335x-timer", dmtimer_systimer_init); 729*52762fbdSTony Lindgren TIMER_OF_DECLARE(systimer_am3ms, "ti,am335x-timer-1ms", dmtimer_systimer_init); 730*52762fbdSTony Lindgren TIMER_OF_DECLARE(systimer_dm814, "ti,dm814-timer", dmtimer_systimer_init); 731*52762fbdSTony Lindgren TIMER_OF_DECLARE(systimer_dm816, "ti,dm816-timer", dmtimer_systimer_init); 732