Ejemplo n.º 1
0
/*
 * The general purpose timer ticks at 1MHz independent if
 * the rest of the system
 */
static void sibyte_set_mode(enum clock_event_mode mode,
                           struct clock_event_device *evt)
{
	unsigned int cpu = smp_processor_id();
	void __iomem *cfg, *init;

	cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
	init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));

	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		__raw_writeq(0, cfg);
		__raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
		__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
			     cfg);
		break;

	case CLOCK_EVT_MODE_ONESHOT:
		/* Stop the timer until we actually program a shot */
	case CLOCK_EVT_MODE_SHUTDOWN:
		__raw_writeq(0, cfg);
		break;

	case CLOCK_EVT_MODE_UNUSED:	/* shuddup gcc */
	case CLOCK_EVT_MODE_RESUME:
		;
	}
}
Ejemplo n.º 2
0
static int sibyte_set_periodic(struct clock_event_device *evt)
{
	unsigned int cpu = smp_processor_id();
	void __iomem *cfg, *init;

	cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
	init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));

	__raw_writeq(0, cfg);
	__raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
	__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, cfg);
	return 0;
}
Ejemplo n.º 3
0
static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
{
	unsigned int cpu = smp_processor_id();
	void __iomem *cfg, *init;

	cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
	init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));

	__raw_writeq(0, cfg);
	__raw_writeq(delta - 1, init);
	__raw_writeq(M_SCD_TIMER_ENABLE, cfg);

	return 0;
}
Ejemplo n.º 4
0
void sb1250_time_init(void)
{
	int cpu = smp_processor_id();
	int irq = K_INT_TIMER_0+cpu;

	/* Only have 4 general purpose timers */
	if (cpu > 3) {
		BUG();
	}

	if (!cpu) {
		/* Use our own gettimeoffset() routine */
		do_gettimeoffset = sb1250_gettimeoffset;
	}

	sb1250_mask_irq(cpu, irq);

	/* Map the timer interrupt to ip[4] of this cpu */
	bus_writeq(IMR_IP4_VAL,
		   IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
			  (irq << 3)));

	/* the general purpose timer ticks at 1 Mhz independent if the rest of the system */
	/* Disable the timer and set up the count */
	bus_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
#ifdef CONFIG_SIMULATION
	bus_writeq(50000 / HZ,
		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
#else
	bus_writeq(1000000/HZ,
		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
#endif

	/* Set the timer running */
	bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));

	sb1250_unmask_irq(cpu, irq);
	sb1250_steal_irq(irq);
	/*
	 * This interrupt is "special" in that it doesn't use the request_irq
	 * way to hook the irq line.  The timer interrupt is initialized early
	 * enough to make this a major pain, and it's also firing enough to
	 * warrant a bit of special case code.  sb1250_timer_interrupt is
	 * called directly from irq_handler.S when IP[4] is set during an
	 * interrupt
	 */
}
Ejemplo n.º 5
0
static cycle_t bcm1480_hpt_read(void)
{
	/* We assume this function is called xtime_lock held. */
	unsigned long count =
		__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
	return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count;
}
Ejemplo n.º 6
0
/*
 * We use our own do_gettimeoffset() instead of the generic one,
 * because the generic one does not work for SMP case.
 * In addition, since we use general timer 0 for system time,
 * we can get accurate intra-jiffy offset without calibration.
 */
unsigned long sb1250_gettimeoffset(void)
{
	unsigned long count =
		bus_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));

	return 1000000/HZ - count;
 }
Ejemplo n.º 7
0
/*
 * We use our own do_gettimeoffset() instead of the generic one,
 * because the generic one does not work for SMP case.
 * In addition, since we use general timer 0 for system time,
 * we can get accurate intra-jiffy offset without calibration.
 */
unsigned long sb1250_gettimeoffset(void)
{
	unsigned long count =
		in64(KSEG1 + A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT));

	return 1000000/HZ - count;
 }
void __init sb1250_clocksource_init(void)
{
	struct clocksource *cs = &bcm1250_clocksource;

	/* Setup hpt using timer #3 but do not enable irq for it */
	__raw_writeq(0,
		     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
						 R_SCD_TIMER_CFG)));
	__raw_writeq(SB1250_HPT_VALUE,
		     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
						 R_SCD_TIMER_INIT)));
	__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
		     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
						 R_SCD_TIMER_CFG)));

<<<<<<< HEAD
void __init sb1250_clocksource_init(void)
{
    struct clocksource *cs = &bcm1250_clocksource;


    __raw_writeq(0,
                 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
                         R_SCD_TIMER_CFG)));
    __raw_writeq(SB1250_HPT_VALUE,
                 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
                         R_SCD_TIMER_INIT)));
    __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
                 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
                         R_SCD_TIMER_CFG)));

    clocksource_register_hz(cs, V_SCD_TIMER_FREQ);
}
static cycle_t sb1250_hpt_read(struct clocksource *cs)
{
    unsigned int count;

    count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT))));

    return SB1250_HPT_VALUE - count;
}
Ejemplo n.º 11
0
static int sibyte_shutdown(struct clock_event_device *evt)
{
	unsigned int cpu = smp_processor_id();
	void __iomem *cfg;

	cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));

	/* Stop the timer until we actually program a shot */
	__raw_writeq(0, cfg);
	return 0;
}
Ejemplo n.º 12
0
void bcm1480_time_init(void)
{
	int cpu = smp_processor_id();
	int irq = K_BCM1480_INT_TIMER_0+cpu;

	/* Only have 4 general purpose timers */
	if (cpu > 3) {
		BUG();
	}

	bcm1480_mask_irq(cpu, irq);

	/* Map the timer interrupt to ip[4] of this cpu */
	__raw_writeq(IMR_IP4_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H)
	      + (irq<<3)));

	/* the general purpose timer ticks at 1 Mhz independent of the rest of the system */
	/* Disable the timer and set up the count */
	__raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
	__raw_writeq(
		BCM1480_HPT_VALUE/HZ
		, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));

	/* Set the timer running */
	__raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
	      IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));

	bcm1480_unmask_irq(cpu, irq);
	bcm1480_steal_irq(irq);
	/*
	 * This interrupt is "special" in that it doesn't use the request_irq
	 * way to hook the irq line.  The timer interrupt is initialized early
	 * enough to make this a major pain, and it's also firing enough to
	 * warrant a bit of special case code.  bcm1480_timer_interrupt is
	 * called directly from irq_handler.S when IP[4] is set during an
	 * interrupt
	 */
}
Ejemplo n.º 13
0
static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
{
	unsigned int cpu = smp_processor_id();
	struct clock_event_device *cd = dev_id;
	void __iomem *cfg;
	unsigned long tmode;

	if (cd->mode == CLOCK_EVT_MODE_PERIODIC)
		tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS;
	else
		tmode = 0;

	/* ACK interrupt */
	cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
	____raw_writeq(tmode, cfg);

	cd->event_handler(cd);

	return IRQ_HANDLED;
}
Ejemplo n.º 14
0
void sb1250_timer_interrupt(struct pt_regs *regs)
{
	int cpu = smp_processor_id();
	int irq = K_INT_TIMER_0+cpu;

	/* Reset the timer */
	out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
	      KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));

	/*
	 * CPU 0 handles the global timer interrupt job
	 */
	if (cpu == 0) {
		ll_timer_interrupt(irq, regs);
	}

	/*
	 * every CPU should do profiling and process accouting
	 */
	ll_local_timer_interrupt(irq, regs);
}
Ejemplo n.º 15
0
void bcm1480_timer_interrupt(void)
{
	int cpu = smp_processor_id();
	int irq = K_BCM1480_INT_TIMER_0 + cpu;

	/* Reset the timer */
	__raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
	      IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));

	if (cpu == 0) {
		/*
		 * CPU 0 handles the global timer interrupt job
		 */
		ll_timer_interrupt(irq);
	}
	else {
		/*
		 * other CPUs should just do profiling and process accounting
		 */
		ll_local_timer_interrupt(irq);
	}
}
Ejemplo n.º 16
0
void sb1250_timer_interrupt(struct pt_regs *regs)
{
	extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
	int cpu = smp_processor_id();
	int irq = K_INT_TIMER_0 + cpu;

	/* Reset the timer */
	__bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
		     IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));

	/*
	 * CPU 0 handles the global timer interrupt job
	 */
	if (cpu == 0) {
		ll_timer_interrupt(irq, regs);
	}

	if (cpu != 0) {
		/*
		 * every CPU should do profiling and process accouting
		 */
		ll_local_timer_interrupt(irq, regs);
	}
}