Пример #1
0
/*
 * Setup the local clock events for a CPU.
 */
void __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
	unsigned long flags;

	twd_calibrate_rate();

	clk->name = "local_timer";
	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
			CLOCK_EVT_FEAT_C3STOP;
	clk->rating = 350;
	clk->set_mode = twd_set_mode;
	clk->set_next_event = twd_set_next_event;
	clk->shift = 20;
	clk->mult = div_sc(twd_timer_rate, NSEC_PER_SEC, clk->shift);
	clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
	clk->min_delta_ns = clockevent_delta2ns(0xf, clk);

	clockevents_register_device(clk);

	/* Make sure our local interrupt controller has this enabled */
	local_irq_save(flags);
	irq_to_desc(clk->irq)->status |= IRQ_NOPROBE;
	get_irq_chip(clk->irq)->unmask(clk->irq);
	local_irq_restore(flags);
}
Пример #2
0
static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
	struct clock_event_device **this_cpu_clk;

	if (!twd_clk)
		twd_clk = twd_get_clock();

	if (!IS_ERR_OR_NULL(twd_clk))
		twd_timer_rate = clk_get_rate(twd_clk);
	else
		twd_calibrate_rate();

	__raw_writel(0, twd_base + TWD_TIMER_CONTROL);

	clk->name = "local_timer";
	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
			CLOCK_EVT_FEAT_C3STOP;
	clk->rating = 350;
	clk->set_mode = twd_set_mode;
	clk->set_next_event = twd_set_next_event;
	clk->irq = twd_ppi;

	this_cpu_clk = __this_cpu_ptr(twd_evt);
	*this_cpu_clk = clk;

	clockevents_config_and_register(clk, twd_timer_rate,
					0xf, 0xffffffff);
	enable_percpu_irq(clk->irq, 0);

	return 0;
}
Пример #3
0
/*
 * Setup the local clock events for a CPU.
 */
void __cpuinit local_timer_setup(void)
{
	unsigned int cpu = smp_processor_id();
	struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
	unsigned long flags;

	twd_calibrate_rate();

	clk->name		= "local_timer";
	clk->features		= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
	clk->rating		= 350;
	clk->set_mode		= local_timer_set_mode;
	clk->set_next_event	= local_timer_set_next_event;
	clk->irq		= IRQ_LOCALTIMER;
	clk->cpumask		= cpumask_of(cpu);
	clk->shift		= 20;
	clk->mult		= div_sc(mpcore_timer_rate, NSEC_PER_SEC, clk->shift);
	clk->max_delta_ns	= clockevent_delta2ns(0xffffffff, clk);
	clk->min_delta_ns	= clockevent_delta2ns(0xf, clk);

	/* Make sure our local interrupt controller has this enabled */
	local_irq_save(flags);
	get_irq_chip(IRQ_LOCALTIMER)->unmask(IRQ_LOCALTIMER);
	local_irq_restore(flags);

	clockevents_register_device(clk);
}
Пример #4
0
/*
 * Setup the local clock events for a CPU.
 */
void __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
	if (!twd_clk)
		twd_clk = twd_get_clock();

	if (!IS_ERR_OR_NULL(twd_clk))
		twd_timer_rate = clk_get_rate(twd_clk);
	else
		twd_calibrate_rate();

	clk->name = "local_timer";
	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
			CLOCK_EVT_FEAT_C3STOP;
	clk->rating = 350;
	clk->set_mode = twd_set_mode;
	clk->set_next_event = twd_set_next_event;

	__get_cpu_var(twd_ce) = clk;

	clockevents_config_and_register(clk, twd_timer_rate,
					0xf, 0xffffffff);

	/* Make sure our local interrupt controller has this enabled */
	gic_enable_ppi(clk->irq);
}
/*
 * Setup the local clock events for a CPU.
 */
static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
    struct clock_event_device **this_cpu_clk;
    int cpu = smp_processor_id();

    /*
     * If the basic setup for this CPU has been done before don't
     * bother with the below.
     */
    if (per_cpu(percpu_setup_called, cpu)) {
        writel_relaxed(0, twd_base + TWD_TIMER_CONTROL);
        clockevents_register_device(*__this_cpu_ptr(twd_evt));
        enable_percpu_irq(clk->irq, 0);
        return 0;
    }
    per_cpu(percpu_setup_called, cpu) = true;

    twd_calibrate_rate();

    /*
     * The following is done once per CPU the first time .setup() is
     * called.
     */
    writel_relaxed(0, twd_base + TWD_TIMER_CONTROL);

    clk->name = "local_timer";
    clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
                    CLOCK_EVT_FEAT_C3STOP;
    clk->rating = 350;
    clk->set_mode = twd_set_mode;
    clk->set_next_event = twd_set_next_event;
    clk->irq = twd_ppi;

    this_cpu_clk = __this_cpu_ptr(twd_evt);
    *this_cpu_clk = clk;

    clockevents_config_and_register(clk, twd_timer_rate,
                                    0xf, 0xffffffff);
    enable_percpu_irq(clk->irq, 0);

    return 0;
}
Пример #6
0
/*
 * Setup the local clock events for a CPU.
 */
void __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
	twd_calibrate_rate();

	clk->name = "local_timer";
	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
			CLOCK_EVT_FEAT_C3STOP;
	clk->rating = 350;
	clk->set_mode = twd_set_mode;
	clk->set_next_event = twd_set_next_event;
	clk->shift = 20;
	clk->mult = div_sc(twd_timer_rate, NSEC_PER_SEC, clk->shift);
	clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
	clk->min_delta_ns = clockevent_delta2ns(0xf, clk);

	/* Make sure our local interrupt controller has this enabled */
	gic_enable_ppi(clk->irq);

	clockevents_register_device(clk);
}
Пример #7
0
static void __cpuinit gt_setup(unsigned long base_paddr, unsigned bits)
{
	if ((read_cpuid_id() & 0xf00000) == 0)
		return;

	twd_clk = twd_get_clock();

	if (!IS_ERR_OR_NULL(twd_clk))
		twd_timer_rate = clk_get_rate(twd_clk);
	else
		twd_calibrate_rate();

	common_setup_called = true;
	
	gt_base = ioremap(base_paddr, SZ_256);
	BUG_ON(!gt_base);

	/* Start global timer */
	__raw_writel(1, gt_base + 0x8);

	tsc_info.type = IPIPE_TSC_TYPE_FREERUNNING;
	tsc_info.freq = twd_timer_rate;
	tsc_info.counter_vaddr = (unsigned long)gt_base;
	tsc_info.u.counter_paddr = base_paddr;
	
	switch(bits) {
	case 64:
		tsc_info.u.mask = 0xffffffffffffffffULL;
		break;
	case 32:
		tsc_info.u.mask = 0xffffffff;
		break;
	default:
		/* Only supported as a 32 bits or 64 bits */
		BUG();
	}

	__ipipe_tsc_register(&tsc_info);
}
Пример #8
0
/*
 * Setup the local clock events for a CPU.
 */
static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
	struct clock_event_device **this_cpu_clk;
	int cpu = smp_processor_id();

	/*
	 * If the basic setup for this CPU has been done before don't
	 * bother with the below.
	 */
	if (per_cpu(percpu_setup_called, cpu)) {
		__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
		clockevents_register_device(*__this_cpu_ptr(twd_evt));
		enable_percpu_irq(clk->irq, 0);
		return 0;
	}
	per_cpu(percpu_setup_called, cpu) = true;

	/*
	 * This stuff only need to be done once for the entire TWD cluster
	 * during the runtime of the system.
	 */
	if (!common_setup_called) {
		twd_clk = twd_get_clock();

		/*
		 * We use IS_ERR_OR_NULL() here, because if the clock stubs
		 * are active we will get a valid clk reference which is
		 * however NULL and will return the rate 0. In that case we
		 * need to calibrate the rate instead.
		 */
		if (!IS_ERR_OR_NULL(twd_clk))
			twd_timer_rate = clk_get_rate(twd_clk);
		else
			twd_calibrate_rate();

		common_setup_called = true;
	}

	/*
	 * The following is done once per CPU the first time .setup() is
	 * called.
	 */
	__raw_writel(0, twd_base + TWD_TIMER_CONTROL);

	clk->name = "local_timer";
	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
			CLOCK_EVT_FEAT_C3STOP;
	clk->rating = 350;
	clk->set_mode = twd_set_mode;
	clk->set_next_event = twd_set_next_event;
	clk->irq = twd_ppi;

#if defined(CONFIG_IPIPE) && defined(CONFIG_SMP)
	printk(KERN_INFO "I-pipe, %lu.%03lu MHz timer\n",
	       twd_timer_rate / 1000000,
	       (twd_timer_rate % 1000000) / 1000);
	clk->ipipe_timer = __this_cpu_ptr(&twd_itimer);
	clk->ipipe_timer->irq = clk->irq;
	clk->ipipe_timer->ack = twd_ack;
	clk->ipipe_timer->min_delay_ticks = 0xf;
#endif

	this_cpu_clk = __this_cpu_ptr(twd_evt);
	*this_cpu_clk = clk;

	clockevents_config_and_register(clk, twd_timer_rate,
					0xf, 0xffffffff);
	enable_percpu_irq(clk->irq, 0);

	return 0;
}