static void __init omap2_gp_clockevent_init(void) { u32 tick_rate; gptimer = omap_dm_timer_request_specific(1); BUG_ON(gptimer == NULL); #if defined(CONFIG_OMAP_32K_TIMER) omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ); #else omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK); #endif tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer)); omap2_gp_timer_irq.dev_id = (void *)gptimer; setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC, clockevent_gpt.shift); clockevent_gpt.max_delta_ns = clockevent_delta2ns(0xffffffff, &clockevent_gpt); clockevent_gpt.min_delta_ns = clockevent_delta2ns(1, &clockevent_gpt); clockevent_gpt.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_gpt); }
static inline int proc44x_start(struct device *dev, u32 start_addr) { struct platform_device *pdev = to_platform_device(dev); struct omap_rproc *obj = (struct omap_rproc *)platform_get_drvdata( to_platform_device(dev)); int ret = 0; /* Enable the Timer that would be used by co-processor */ if (obj->timer_id >= 0) { obj->dmtimer = omap_dm_timer_request_specific(obj->timer_id); if (!obj->dmtimer) { ret = -EBUSY; goto err_start; } omap_dm_timer_set_int_enable(obj->dmtimer, OMAP_TIMER_INT_OVERFLOW); omap_dm_timer_set_source(obj->dmtimer, OMAP_TIMER_SRC_SYS_CLK); } ret = omap_device_enable(pdev); if (ret) goto err_start; obj->state = OMAP_RPROC_RUNNING; return 0; err_start: dev_err(dev, "%s error 0x%x\n", __func__, ret); return ret; }
/** * dsp_gpt_wait_overflow - set gpt overflow and wait for fixed timeout * @clk_id: GP Timer clock id. * @load: Overflow value. * * Sets an overflow interrupt for the desired GPT waiting for a timeout * of 5 msecs for the interrupt to occur. */ void dsp_gpt_wait_overflow(short int clk_id, unsigned int load) { struct omap_dm_timer *gpt = timer[clk_id - 1]; unsigned long timeout; if (!gpt) return; /* Enable overflow interrupt */ omap_dm_timer_set_int_enable(gpt, OMAP_TIMER_INT_OVERFLOW); /* * Set counter value to overflow counter after * one tick and start timer. */ omap_dm_timer_set_load_start(gpt, 0, load); /* Wait 80us for timer to overflow */ udelay(80); timeout = msecs_to_jiffies(5); /* Check interrupt status and wait for interrupt */ while (!(omap_dm_timer_read_status(gpt) & OMAP_TIMER_INT_OVERFLOW)) { if (time_is_after_jiffies(timeout)) { pr_err("%s: GPTimer interrupt failed\n", __func__); break; } } }
static void gptimer_stop(void) { omap_dm_timer_set_int_enable(gptimer, 0); free_irq(omap_dm_timer_get_irq(gptimer), NULL); omap_dm_timer_free(gptimer); gptimer = NULL; }
static int gptimer_start(void) { int err; u32 count = counter_config[0].count; BUG_ON(gptimer != NULL); /* First try to request timers from CORE power domain for OMAP3 */ if (cpu_is_omap34xx()) { gptimer = omap_dm_timer_request_specific(10); if (gptimer == NULL) gptimer = omap_dm_timer_request_specific(11); } /* Just any timer would be fine */ if (gptimer == NULL) gptimer = omap_dm_timer_request(); if (gptimer == NULL) return -ENODEV; omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ); err = request_irq(omap_dm_timer_get_irq(gptimer), gptimer_interrupt, IRQF_DISABLED, "oprofile gptimer", NULL); if (err) { omap_dm_timer_free(gptimer); gptimer = NULL; printk(KERN_ERR "oprofile: unable to request gptimer IRQ\n"); return err; } if (count < 1) count = 1; omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - count); omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); return 0; }
static int __devinit cloudsurfer_wakeup_probe(struct platform_device *pdev) { struct cloudsurfer_wakeup_struct *wkup; struct input_dev *wkup_in; u32 tick_rate, cycles; int err; /* Data structure allocation */ wkup = kzalloc(sizeof(struct cloudsurfer_wakeup_struct), GFP_KERNEL); wkup_in = input_allocate_device(); if (!wkup_in) { printk("CLOUDSURFER - Can't allocate wakeup timer input\n"); err = -ENOMEM; goto error_input_dev; } /* Timer allocation and setup */ if ( (wkup->timer=omap_dm_timer_request_specific(1)) == NULL ) { printk("CLOUDSURFER - can't allocate wakeup timer\n"); err = -ENODEV; goto error_timer; } wkup->irq = omap_dm_timer_get_irq(wkup->timer); omap_dm_timer_set_source(wkup->timer,OMAP_TIMER_SRC_32_KHZ); tick_rate = clk_get_rate(omap_dm_timer_get_fclk(wkup->timer)); cycles = tick_rate * wakeup_seconds; omap_dm_timer_stop(wkup->timer); input_set_capability(wkup_in,EV_MSC,1); input_set_capability(wkup_in,EV_MSC,2); wkup_in->name = "cloudsurfer-wakeup"; wkup_in->phys = "cloudsurfer-wakeup/input0"; wkup_in->dev.parent = &pdev->dev; cloudsurfer_irq_data.dev_id = wkup_in; setup_irq(wkup->irq,&cloudsurfer_irq_data); input_set_drvdata(wkup_in, wkup); err = input_register_device(wkup_in); if (err) { printk("CLOUDSURFER -Can't register wakeup timer: %d\n", err); goto error_register; } omap_dm_timer_set_int_enable(wkup->timer,OMAP_TIMER_INT_OVERFLOW); omap_dm_timer_set_load_start(wkup->timer, 1, 0xffffffff - cycles); platform_set_drvdata(pdev, wkup_in); return 0; error_register: free_irq(wkup->irq, NULL); error_timer: input_free_device(wkup_in); error_input_dev: kfree(wkup); return err; }
static irqreturn_t lirc_rx51_interrupt_handler(int irq, void *ptr) { unsigned int retval; struct lirc_rx51 *lirc_rx51 = ptr; retval = omap_dm_timer_read_status(lirc_rx51->pulse_timer); if (!retval) return IRQ_NONE; if (retval & ~OMAP_TIMER_INT_MATCH) dev_err_ratelimited(lirc_rx51->dev, ": Unexpected interrupt source: %x\n", retval); omap_dm_timer_write_status(lirc_rx51->pulse_timer, OMAP_TIMER_INT_MATCH | OMAP_TIMER_INT_OVERFLOW | OMAP_TIMER_INT_CAPTURE); if (lirc_rx51->wbuf_index < 0) { dev_err_ratelimited(lirc_rx51->dev, ": BUG wbuf_index has value of %i\n", lirc_rx51->wbuf_index); goto end; } /* * If we happen to hit an odd latency spike, loop through the * pulses until we catch up. */ do { if (lirc_rx51->wbuf_index >= WBUF_LEN) goto end; if (lirc_rx51->wbuf[lirc_rx51->wbuf_index] == -1) goto end; if (lirc_rx51->wbuf_index % 2) lirc_rx51_off(lirc_rx51); else lirc_rx51_on(lirc_rx51); retval = pulse_timer_set_timeout(lirc_rx51, lirc_rx51->wbuf[lirc_rx51->wbuf_index]); lirc_rx51->wbuf_index++; } while (retval); return IRQ_HANDLED; end: /* Stop TX here */ lirc_rx51_off(lirc_rx51); lirc_rx51->wbuf_index = -1; omap_dm_timer_stop(lirc_rx51->pwm_timer); omap_dm_timer_stop(lirc_rx51->pulse_timer); omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer, 0); wake_up_interruptible(&lirc_rx51->wqueue); return IRQ_HANDLED; }
int finish_gptimer12 ( void ) { omap_dm_timer_stop( battery_timer ); omap_dm_timer_write_status( battery_timer, OMAP_TIMER_INT_OVERFLOW ); omap_dm_timer_set_int_enable( battery_timer, 0 ); return 0; }
// Initialize the kernel module static int __init gptimer_test_init(void) { int ret = 0; struct clk *gt_fclk; uint32_t gt_rate; printk("gptimer test: starting moudle init\n"); // request a timer (we are asking for ANY open timer, see dmtimer.c for details on how this works) timer_ptr = omap_dm_timer_request(); if(timer_ptr == NULL){ // oops, no timers available printk("gptimer test: No more gp timers available, bailing out\n"); return -1; } // set the clock source to system clock omap_dm_timer_set_source(timer_ptr, OMAP_TIMER_SRC_SYS_CLK); // set prescalar to 1:1 omap_dm_timer_set_prescaler(timer_ptr, 32); // figure out what IRQ our timer triggers timer_irq = omap_dm_timer_get_irq(timer_ptr); // install our IRQ handler for our timer ret = request_irq(timer_irq, timer_irq_handler, IRQF_DISABLED | IRQF_TIMER , "gptimer test", timer_irq_handler); if(ret){ printk("gptimer test: request_irq failed (on irq %d), bailing out\n", timer_irq); return ret; } // get clock rate in Hz gt_fclk = omap_dm_timer_get_fclk(timer_ptr); gt_rate = clk_get_rate(gt_fclk); // set preload, and autoreload // we set it to the clock rate in order to get 1 overflow every second omap_dm_timer_set_load(timer_ptr, 1, 0xFFFFFFFF - gt_rate); // setup timer to trigger our IRQ on the overflow event omap_dm_timer_set_int_enable(timer_ptr, OMAP_TIMER_INT_OVERFLOW); // start the timer! omap_dm_timer_start(timer_ptr); // done! printk("gptimer test: GP Timer initialized and started (%lu Hz, IRQ %d)\n", (long unsigned)gt_rate, timer_irq); // return sucsess return 0; }
static void __init omap2_gp_clockevent_init(void) { u32 tick_rate; int src; u32* time_base = ioremap(0x4A318000, SZ_4K); inited = 1; gptimer = omap_dm_timer_request_specific(gptimer_id); BUG_ON(gptimer == NULL); gptimer_wakeup = gptimer; #if defined(CONFIG_OMAP_32K_TIMER) src = OMAP_TIMER_SRC_32_KHZ; #else src = OMAP_TIMER_SRC_SYS_CLK; WARN(gptimer_id == 12, "WARNING: GPTIMER12 can only use the " "secure 32KiHz clock source\n"); #endif if (gptimer_id != 12) WARN(IS_ERR_VALUE(omap_dm_timer_set_source(gptimer, src)), "timer-gp: omap_dm_timer_set_source() failed\n"); tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer)); pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n", gptimer_id, tick_rate); print_timer(time_base); omap2_gp_timer_irq.dev_id = (void *)gptimer; //TODO: slow for safety omap_dm_timer_set_load_start(gptimer, 1, 0); print_timer(time_base); setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC, clockevent_gpt.shift); clockevent_gpt.max_delta_ns = clockevent_delta2ns(0xffffffff, &clockevent_gpt); clockevent_gpt.min_delta_ns = clockevent_delta2ns(3, &clockevent_gpt); /* Timer internal resynch latency. */ clockevent_gpt.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_gpt); omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); print_timer(time_base); }
static int lirc_rx51_free_port(struct lirc_rx51 *lirc_rx51) { omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer, 0); free_irq(lirc_rx51->irq_num, lirc_rx51); lirc_rx51_off(lirc_rx51); omap_dm_timer_disable(lirc_rx51->pwm_timer); omap_dm_timer_disable(lirc_rx51->pulse_timer); omap_dm_timer_free(lirc_rx51->pwm_timer); omap_dm_timer_free(lirc_rx51->pulse_timer); lirc_rx51->wbuf_index = -1; return 0; }
static int init_timing_params(struct lirc_rx51 *lirc_rx51) { u32 load, match; load = -(lirc_rx51->fclk_khz * 1000 / lirc_rx51->freq); match = -(lirc_rx51->duty_cycle * -load / 100); omap_dm_timer_set_load(lirc_rx51->pwm_timer, 1, load); omap_dm_timer_set_match(lirc_rx51->pwm_timer, 1, match); omap_dm_timer_write_counter(lirc_rx51->pwm_timer, TIMER_MAX_VALUE - 2); omap_dm_timer_start(lirc_rx51->pwm_timer); omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer, 0); omap_dm_timer_start(lirc_rx51->pulse_timer); lirc_rx51->match = 0; return 0; }
static void __init omap2_gp_clockevent_init(void) { u32 tick_rate; int src; inited = 1; gptimer = omap_dm_timer_request_specific(gptimer_id); BUG_ON(gptimer == NULL); #if defined(CONFIG_OMAP_32K_TIMER) src = OMAP_TIMER_SRC_32_KHZ; #else src = OMAP_TIMER_SRC_SYS_CLK; WARN(gptimer_id == 12, "WARNING: GPTIMER12 can only use the " "secure 32KiHz clock source\n"); #endif if (gptimer_id != 12) WARN(IS_ERR_VALUE(omap_dm_timer_set_source(gptimer, src)), "timer-gp: omap_dm_timer_set_source() failed\n"); tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer)); if (cpu_is_omap44xx()) /* Assuming 32kHz clk is driving GPT1 */ tick_rate = 32768; /* FIXME: */ pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n", gptimer_id, tick_rate); omap2_gp_timer_irq.dev_id = (void *)gptimer; setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC, clockevent_gpt.shift); clockevent_gpt.max_delta_ns = clockevent_delta2ns(0xffffffff, &clockevent_gpt); clockevent_gpt.min_delta_ns = clockevent_delta2ns(3, &clockevent_gpt); /* Timer internal resynch latency. */ clockevent_gpt.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_gpt); }
static int __init omap4_setup_gpt2(void) { /* Set up GPT2 for the WA */ gptimer2 = omap_dm_timer_request_specific(2); BUG_ON(gptimer2 == NULL); printk(KERN_INFO "Enabling AXI2OCP errata Fix \n"); omap_dm_timer_set_source(gptimer2, OMAP_TIMER_SRC_32_KHZ); gpt2_timer_irq.dev_id = (void *)gptimer2; setup_irq(omap_dm_timer_get_irq(gptimer2), &gpt2_timer_irq); omap_dm_timer_set_int_enable(gptimer2, OMAP_TIMER_INT_OVERFLOW); /* * Timer reload value is used based on mpu @ 600 MHz * And hence bridge is at 300 MHz. 65K cycle = 216 uS * 6 * 1/32 kHz => ~187 us */ omap_dm_timer_set_load_start(gptimer2, 1, 0xffffff06); return 0; }
static int pulse_timer_set_timeout(struct lirc_rx51 *lirc_rx51, int usec) { int counter; BUG_ON(usec < 0); if (lirc_rx51->match == 0) counter = omap_dm_timer_read_counter(lirc_rx51->pulse_timer); else counter = lirc_rx51->match; counter += (u32)(lirc_rx51->fclk_khz * usec / (1000)); omap_dm_timer_set_match(lirc_rx51->pulse_timer, 1, counter); omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer, OMAP_TIMER_INT_MATCH); if (tics_after(omap_dm_timer_read_counter(lirc_rx51->pulse_timer), counter)) { return 1; } return 0; }