Commit dfa762e1 authored by Steven J. Hill's avatar Steven J. Hill Committed by Ralf Baechle

MIPS: Refactor GIC clocksource code.

Reorganize some of the GIC clocksource driver code. Below is a list of
the various changes.

  * No longer select CSRC_GIC by default for Malta platform.
  * Limit choice for either the GIC or R4K clocksource, not both.
  * Change location in Makefile.
  * Created new 'gic_read_count' function in common 'irq-gic.c' file.
  * Change 'git_hpt_read' function in 'csrc-gic.c' to use new function.
  * Surround GIC specific code in Malta platform code with #ifdef's.
  * Only initialize the GIC clocksource if it was selected. Original
    code called it unconditionally if a GIC was found.
Signed-off-by: default avatarSteven J. Hill <Steven.Hill@imgtec.com>
parent 28ea2151
...@@ -337,6 +337,7 @@ config MIPS_SEAD3 ...@@ -337,6 +337,7 @@ config MIPS_SEAD3
select BOOT_RAW select BOOT_RAW
select CEVT_R4K select CEVT_R4K
select CSRC_R4K select CSRC_R4K
select CSRC_GIC
select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_VI
select CPU_MIPSR2_IRQ_EI select CPU_MIPSR2_IRQ_EI
select DMA_NONCOHERENT select DMA_NONCOHERENT
......
...@@ -359,6 +359,9 @@ struct gic_shared_intr_map { ...@@ -359,6 +359,9 @@ struct gic_shared_intr_map {
/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
#define GIC_PIN_TO_VEC_OFFSET (1) #define GIC_PIN_TO_VEC_OFFSET (1)
#include <linux/clocksource.h>
#include <linux/irq.h>
extern unsigned int gic_present; extern unsigned int gic_present;
extern unsigned int gic_frequency; extern unsigned int gic_frequency;
extern unsigned long _gic_base; extern unsigned long _gic_base;
...@@ -372,6 +375,7 @@ extern void gic_init(unsigned long gic_base_addr, ...@@ -372,6 +375,7 @@ extern void gic_init(unsigned long gic_base_addr,
extern void gic_clocksource_init(unsigned int); extern void gic_clocksource_init(unsigned int);
extern unsigned int gic_get_int(void); extern unsigned int gic_get_int(void);
extern cycle_t gic_read_count(void);
extern void gic_send_ipi(unsigned int intr); extern void gic_send_ipi(unsigned int intr);
extern unsigned int plat_ipi_call_int_xlate(unsigned int); extern unsigned int plat_ipi_call_int_xlate(unsigned int);
extern unsigned int plat_ipi_resched_int_xlate(unsigned int); extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
......
...@@ -23,11 +23,11 @@ obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o ...@@ -23,11 +23,11 @@ obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
obj-$(CONFIG_CSRC_GIC) += csrc-gic.o
obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o
obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o
obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
obj-$(CONFIG_CSRC_GIC) += csrc-gic.o
obj-$(CONFIG_SYNC_R4K) += sync-r4k.o obj-$(CONFIG_SYNC_R4K) += sync-r4k.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_STACKTRACE) += stacktrace.o
......
...@@ -5,23 +5,14 @@ ...@@ -5,23 +5,14 @@
* *
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
*/ */
#include <linux/clocksource.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/time.h>
#include <asm/time.h>
#include <asm/gic.h> #include <asm/gic.h>
static cycle_t gic_hpt_read(struct clocksource *cs) static cycle_t gic_hpt_read(struct clocksource *cs)
{ {
unsigned int hi, hi2, lo; return gic_read_count();
do {
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi);
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo);
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2);
} while (hi2 != hi);
return (((cycle_t) hi) << 32) + lo;
} }
static struct clocksource gic_clocksource = { static struct clocksource gic_clocksource = {
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/clocksource.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/gic.h> #include <asm/gic.h>
...@@ -32,6 +33,21 @@ static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; ...@@ -32,6 +33,21 @@ static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
static struct gic_pending_regs pending_regs[NR_CPUS]; static struct gic_pending_regs pending_regs[NR_CPUS];
static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
#ifdef CONFIG_CSRC_GIC
cycle_t gic_read_count(void)
{
unsigned int hi, hi2, lo;
do {
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi);
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo);
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2);
} while (hi2 != hi);
return (((cycle_t) hi) << 32) + lo;
}
#endif
unsigned int gic_get_timer_pending(void) unsigned int gic_get_timer_pending(void)
{ {
unsigned int vpe_pending; unsigned int vpe_pending;
......
...@@ -71,7 +71,9 @@ static void __init estimate_frequencies(void) ...@@ -71,7 +71,9 @@ static void __init estimate_frequencies(void)
{ {
unsigned long flags; unsigned long flags;
unsigned int count, start; unsigned int count, start;
#ifdef CONFIG_IRQ_GIC
unsigned int giccount = 0, gicstart = 0; unsigned int giccount = 0, gicstart = 0;
#endif
local_irq_save(flags); local_irq_save(flags);
...@@ -81,26 +83,32 @@ static void __init estimate_frequencies(void) ...@@ -81,26 +83,32 @@ static void __init estimate_frequencies(void)
/* Initialize counters. */ /* Initialize counters. */
start = read_c0_count(); start = read_c0_count();
#ifdef CONFIG_IRQ_GIC
if (gic_present) if (gic_present)
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart); GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart);
#endif
/* Read counter exactly on falling edge of update flag. */ /* Read counter exactly on falling edge of update flag. */
while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (CMOS_READ(RTC_REG_A) & RTC_UIP);
while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
count = read_c0_count(); count = read_c0_count();
#ifdef CONFIG_IRQ_GIC
if (gic_present) if (gic_present)
GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount); GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount);
#endif
local_irq_restore(flags); local_irq_restore(flags);
count -= start; count -= start;
if (gic_present)
giccount -= gicstart;
mips_hpt_frequency = count; mips_hpt_frequency = count;
if (gic_present)
#ifdef CONFIG_IRQ_GIC
if (gic_present) {
giccount -= gicstart;
gic_frequency = giccount; gic_frequency = giccount;
}
#endif
} }
void read_persistent_clock(struct timespec *ts) void read_persistent_clock(struct timespec *ts)
...@@ -156,24 +164,27 @@ void __init plat_time_init(void) ...@@ -156,24 +164,27 @@ void __init plat_time_init(void)
(prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
freq *= 2; freq *= 2;
freq = freqround(freq, 5000); freq = freqround(freq, 5000);
pr_debug("CPU frequency %d.%02d MHz\n", freq/1000000, printk("CPU frequency %d.%02d MHz\n", freq/1000000,
(freq%1000000)*100/1000000); (freq%1000000)*100/1000000);
cpu_khz = freq / 1000; cpu_khz = freq / 1000;
if (gic_present) { mips_scroll_message();
freq = freqround(gic_frequency, 5000);
pr_debug("GIC frequency %d.%02d MHz\n", freq/1000000,
(freq%1000000)*100/1000000);
gic_clocksource_init(gic_frequency);
} else
init_r4k_clocksource();
#ifdef CONFIG_I8253 #ifdef CONFIG_I8253
/* Only Malta has a PIT. */ /* Only Malta has a PIT. */
setup_pit_timer(); setup_pit_timer();
#endif #endif
mips_scroll_message(); #ifdef CONFIG_IRQ_GIC
if (gic_present) {
freq = freqround(gic_frequency, 5000);
printk("GIC frequency %d.%02d MHz\n", freq/1000000,
(freq%1000000)*100/1000000);
#ifdef CONFIG_CSRC_GIC
gic_clocksource_init(gic_frequency);
#endif
}
#endif
plat_perf_setup(); plat_perf_setup();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment