void __init nmdk_timer_init(void) { unsigned long rate; struct clk *clk0; int ret; clk0 = clk_get_sys("mtu0", NULL); BUG_ON(IS_ERR(clk0)); ret = clk_prepare_enable(clk0); BUG_ON(ret != 0); /* * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz * for ux500. * Use a divide-by-16 counter if the tick rate is more than 32MHz. * At 32 MHz, the timer (with 32 bit counter) can be programmed * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer * with 16 gives too low timer resolution. */ rate = clk_get_rate(clk0); if (rate > 32000000) { rate /= 16; clk_prescale = MTU_CRn_PRESCALE_16; } else { clk_prescale = MTU_CRn_PRESCALE_1; } nmdk_cycle = (rate + HZ/2) / HZ; /* Timer 0 is the free running clocksource */ nmdk_clksrc_reset(); if (clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0", rate, 200, 32, clocksource_mmio_readl_down)) pr_err("timer: failed to initialize clock source %s\n", "mtu_0"); #ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK setup_sched_clock(nomadik_read_sched_clock, 32, rate); #endif /* Timer 1 is used for events, register irq and clockevents */ setup_irq(IRQ_MTU0, &nmdk_timer_irq); nmdk_clkevt.cpumask = cpumask_of(0); clockevents_config_and_register(&nmdk_clkevt, rate, 2, 0xffffffffU); #ifdef ARCH_HAS_READ_CURRENT_TIMER set_delay_fn(nmdk_timer_delay_loop); #endif }
void __init mtu_timer_init(void) { unsigned long rate; struct clk *clk0; clk0 = clk_get_sys("mtu0", NULL); BUG_ON(IS_ERR(clk0)); rate = clk_get_rate(clk0); clk_enable(clk0); /* * Set scale and timer for sched_clock */ setup_sched_clock(rate); u8500_cycle = (rate + HZ/2) / HZ; /* Save global pointer to mtu, used by functions above */ if (cpu_is_u5500()) { mtu0_base = ioremap(U5500_MTU0_BASE, SZ_4K); } else if (cpu_is_u8500()) { mtu0_base = ioremap(U8500_MTU0_BASE, SZ_4K); } else { ux500_unknown_soc(); } /* Restart clock source */ mtu_clocksource_reset(); /* Now the scheduling clock is ready */ u8500_clksrc.read = u8500_read_timer; u8500_clksrc.mult = clocksource_hz2mult(rate, u8500_clksrc.shift); clocksource_register(&u8500_clksrc); /* Register irq and clockevents */ /* We can sleep for max 10s (actually max is longer) */ clockevents_calc_mult_shift(&u8500_mtu_clkevt, rate, 10); u8500_mtu_clkevt.max_delta_ns = clockevent_delta2ns(0xffffffff, &u8500_mtu_clkevt); u8500_mtu_clkevt.min_delta_ns = clockevent_delta2ns(0xff, &u8500_mtu_clkevt); setup_irq(IRQ_MTU0, &u8500_timer_irq); clockevents_register_device(&u8500_mtu_clkevt); #ifdef ARCH_HAS_READ_CURRENT_TIMER set_delay_fn(mtu_timer_delay_loop); #endif }
void __init nmdk_timer_init(void) { unsigned long rate; struct clk *clk0; unsigned long min_delta_ticks; clk0 = clk_get_sys("mtu0", NULL); BUG_ON(IS_ERR(clk0)); clk_enable(clk0); /* * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz * for ux500. * Use a divide-by-16 counter if the tick rate is more than 32MHz. * At 32 MHz, the timer (with 32 bit counter) can be programmed * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer * with 16 gives too low timer resolution. */ rate = clk_get_rate(clk0); if (rate > 32000000) { rate /= 16; clk_prescale = MTU_CRn_PRESCALE_16; } else { clk_prescale = MTU_CRn_PRESCALE_1; } nmdk_cycle = (rate + HZ/2) / HZ; /* Timer 0 is the free running clocksource */ nmdk_clksrc_reset(); if (clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0", rate, 200, 32, clocksource_mmio_readl_down)) pr_err("timer: failed to initialize clock source %s\n", "mtu_0"); #ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK setup_sched_clock(nomadik_read_sched_clock, 32, rate); #endif /* Timer 1 is used for events */ clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); nmdk_clkevt.max_delta_ns = clockevent_delta2ns(0xffffffff, &nmdk_clkevt); /* When ulppll is disabled timer is working on 32kHz clock. */ min_delta_ticks = prcmu_is_ulppll_disabled()? 0x5 : 0x2; nmdk_clkevt.min_delta_ns = clockevent_delta2ns(min_delta_ticks, &nmdk_clkevt); nmdk_clkevt.cpumask = cpumask_of(0); /* Register irq and clockevents */ setup_irq(IRQ_MTU0, &nmdk_timer_irq); clockevents_register_device(&nmdk_clkevt); #ifdef ARCH_HAS_READ_CURRENT_TIMER if (!prcmu_is_ulppll_disabled()) set_delay_fn(nmdk_timer_delay_loop); #endif }