summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-davinci/devices.c47
-rw-r--r--arch/arm/mach-davinci/dm355.c14
-rw-r--r--arch/arm/mach-davinci/dm644x.c14
-rw-r--r--arch/arm/mach-davinci/dm646x.c14
-rw-r--r--arch/arm/mach-davinci/include/mach/common.h13
-rw-r--r--arch/arm/mach-davinci/include/mach/time.h34
-rw-r--r--arch/arm/mach-davinci/time.c100
7 files changed, 181 insertions, 55 deletions
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 56c19319a7d2..36c528ff30f9 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -25,6 +25,7 @@
#include <mach/mux.h>
#include <mach/edma.h>
#include <mach/mmc.h>
+#include <mach/time.h>
#define DAVINCI_I2C_BASE 0x01C21000
#define DAVINCI_MMCSD0_BASE 0x01E10000
@@ -235,6 +236,52 @@ static void davinci_init_wdt(void)
/*-------------------------------------------------------------------------*/
+struct davinci_timer_instance davinci_timer_instance[2] = {
+ {
+ .base = IO_ADDRESS(DAVINCI_TIMER0_BASE),
+ .bottom_irq = IRQ_TINT0_TINT12,
+ .top_irq = IRQ_TINT0_TINT34,
+ },
+ {
+ .base = IO_ADDRESS(DAVINCI_TIMER1_BASE),
+ .bottom_irq = IRQ_TINT1_TINT12,
+ .top_irq = IRQ_TINT1_TINT34,
+ },
+};
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE)
+
+void davinci_init_emac(struct emac_platform_data *pdata)
+{
+ DECLARE_MAC_BUF(buf);
+
+ if (cpu_is_davinci_dm644x())
+ dm644x_init_emac(pdata);
+ else if (cpu_is_davinci_dm646x())
+ dm646x_init_emac(pdata);
+
+ /* if valid MAC exists, don't re-register */
+ if (is_valid_ether_addr(pdata->mac_addr))
+ return;
+ else {
+ /* Use random MAC if none passed */
+ random_ether_addr(pdata->mac_addr);
+
+ printk(KERN_WARNING "%s: using random MAC addr: %s\n",
+ __func__, print_mac(buf, pdata->mac_addr));
+ }
+}
+
+#else
+
+void davinci_init_emac(struct emac_platform_data *unused) {}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
static int __init davinci_init_devices(void)
{
/* please keep these calls, and their implementations above,
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index e8c01ffe818a..293a419a4a8e 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -25,6 +25,7 @@
#include <mach/psc.h>
#include <mach/mux.h>
#include <mach/irqs.h>
+#include <mach/time.h>
#include <mach/common.h>
#include "clock.h"
@@ -616,6 +617,18 @@ static void __iomem *dm355_psc_bases[] = {
IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
};
+/*
+ * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
+ * T0_TOP: Timer 0, top : clocksource for generic timekeeping
+ * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
+ * T1_TOP: Timer 1, top : <unused>
+ */
+struct davinci_timer_info dm355_timer_info = {
+ .timers = davinci_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
static struct davinci_soc_info davinci_soc_info_dm355 = {
.io_desc = dm355_io_desc,
.io_desc_num = ARRAY_SIZE(dm355_io_desc),
@@ -632,6 +645,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = {
.intc_type = DAVINCI_INTC_TYPE_AINTC,
.intc_irq_prios = dm355_default_priorities,
.intc_irq_num = DAVINCI_N_AINTC_IRQ,
+ .timer_info = &dm355_timer_info,
};
void __init dm355_init(void)
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 5c6a7b175786..8e9385c34853 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -22,6 +22,7 @@
#include <mach/irqs.h>
#include <mach/psc.h>
#include <mach/mux.h>
+#include <mach/time.h>
#include <mach/common.h>
#include "clock.h"
@@ -559,6 +560,18 @@ static void __iomem *dm644x_psc_bases[] = {
IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
};
+/*
+ * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
+ * T0_TOP: Timer 0, top : clocksource for generic timekeeping
+ * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
+ * T1_TOP: Timer 1, top : <unused>
+ */
+struct davinci_timer_info dm644x_timer_info = {
+ .timers = davinci_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
static struct davinci_soc_info davinci_soc_info_dm644x = {
.io_desc = dm644x_io_desc,
.io_desc_num = ARRAY_SIZE(dm644x_io_desc),
@@ -575,6 +588,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
.intc_type = DAVINCI_INTC_TYPE_AINTC,
.intc_irq_prios = dm644x_default_priorities,
.intc_irq_num = DAVINCI_N_AINTC_IRQ,
+ .timer_info = &dm644x_timer_info,
};
void __init dm644x_init(void)
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index beb522e8a1a5..219063f4d000 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -22,6 +22,7 @@
#include <mach/irqs.h>
#include <mach/psc.h>
#include <mach/mux.h>
+#include <mach/time.h>
#include <mach/common.h>
#include "clock.h"
@@ -538,6 +539,18 @@ static void __iomem *dm646x_psc_bases[] = {
IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
};
+/*
+ * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
+ * T0_TOP: Timer 0, top : clocksource for generic timekeeping
+ * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
+ * T1_TOP: Timer 1, top : <unused>
+ */
+struct davinci_timer_info dm646x_timer_info = {
+ .timers = davinci_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
static struct davinci_soc_info davinci_soc_info_dm646x = {
.io_desc = dm646x_io_desc,
.io_desc_num = ARRAY_SIZE(dm646x_io_desc),
@@ -554,6 +567,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = {
.intc_type = DAVINCI_INTC_TYPE_AINTC,
.intc_irq_prios = dm646x_default_priorities,
.intc_irq_num = DAVINCI_N_AINTC_IRQ,
+ .timer_info = &dm646x_timer_info,
};
void __init dm646x_init(void)
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 838ae13595a4..90b43be1174e 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -25,6 +25,18 @@ extern void setup_usb(unsigned mA, unsigned potpgt_msec);
/* parameters describe VBUS sourcing for host mode */
extern void setup_usb(unsigned mA, unsigned potpgt_msec);
+struct davinci_timer_instance {
+ void __iomem *base;
+ u32 bottom_irq;
+ u32 top_irq;
+};
+
+struct davinci_timer_info {
+ struct davinci_timer_instance *timers;
+ unsigned int clockevent_id;
+ unsigned int clocksource_id;
+};
+
/* SoC specific init support */
struct davinci_soc_info {
struct map_desc *io_desc;
@@ -44,6 +56,7 @@ struct davinci_soc_info {
int intc_type;
u8 *intc_irq_prios;
unsigned long intc_irq_num;
+ struct davinci_timer_info *timer_info;
};
extern struct davinci_soc_info davinci_soc_info;
diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h
new file mode 100644
index 000000000000..1428d77c989e
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/time.h
@@ -0,0 +1,34 @@
+/*
+ * Local header file for DaVinci time code.
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H
+#define __ARCH_ARM_MACH_DAVINCI_TIME_H
+
+#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
+#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
+
+enum {
+ T0_BOT,
+ T0_TOP,
+ T1_BOT,
+ T1_TOP,
+ NUM_TIMERS
+};
+
+#define IS_TIMER1(id) (id & 0x2)
+#define IS_TIMER0(id) (!IS_TIMER1(id))
+#define IS_TIMER_TOP(id) ((id & 0x1))
+#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id))
+
+#define ID_TO_TIMER(id) (IS_TIMER1(id) != 0)
+
+extern struct davinci_timer_instance davinci_timer_instance[];
+
+#endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index efbbc2ac63b4..faafb897f4bd 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -29,42 +29,23 @@
#include <asm/errno.h>
#include <mach/io.h>
#include <mach/cputype.h>
+#include <mach/time.h>
#include "clock.h"
static struct clock_event_device clockevent_davinci;
static unsigned int davinci_clock_tick_rate;
-#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
-#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
#define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00)
-enum {
- T0_BOT = 0, T0_TOP, T1_BOT, T1_TOP, NUM_TIMERS,
-};
-
-#define IS_TIMER1(id) (id & 0x2)
-#define IS_TIMER0(id) (!IS_TIMER1(id))
-#define IS_TIMER_TOP(id) ((id & 0x1))
-#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id))
-
-static int timer_irqs[NUM_TIMERS] = {
- IRQ_TINT0_TINT12,
- IRQ_TINT0_TINT34,
- IRQ_TINT1_TINT12,
- IRQ_TINT1_TINT34,
-};
-
/*
* This driver configures the 2 64-bit count-up timers as 4 independent
* 32-bit count-up timers used as follows:
- *
- * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
- * T0_TOP: Timer 0, top : clocksource for generic timekeeping
- * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
- * T1_TOP: Timer 1, top : <unused>
*/
-#define TID_CLOCKEVENT T0_BOT
-#define TID_CLOCKSOURCE T0_TOP
+
+enum {
+ TID_CLOCKEVENT,
+ TID_CLOCKSOURCE,
+};
/* Timer register offsets */
#define PID12 0x0
@@ -119,6 +100,13 @@ static struct timer_s timers[];
#define TIMER_OPTS_ONESHOT 0x01
#define TIMER_OPTS_PERIODIC 0x02
+static char *id_to_name[] = {
+ [T0_BOT] = "timer0_0",
+ [T0_TOP] = "timer0_1",
+ [T1_BOT] = "timer1_0",
+ [T1_TOP] = "timer1_1",
+};
+
static int timer32_config(struct timer_s *t)
{
u32 tcr = __raw_readl(t->base + TCR);
@@ -183,13 +171,14 @@ static struct timer_s timers[] = {
static void __init timer_init(void)
{
- u32 phys_bases[] = {DAVINCI_TIMER0_BASE, DAVINCI_TIMER1_BASE};
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct davinci_timer_instance *dtip = soc_info->timer_info->timers;
int i;
/* Global init of each 64-bit timer as a whole */
for(i=0; i<2; i++) {
u32 tgcr;
- void __iomem *base = IO_ADDRESS(phys_bases[i]);
+ void __iomem *base = dtip[i].base;
/* Disabled, Internal clock source */
__raw_writel(0, base + TCR);
@@ -215,33 +204,30 @@ static void __init timer_init(void)
/* Init of each timer as a 32-bit timer */
for (i=0; i< ARRAY_SIZE(timers); i++) {
struct timer_s *t = &timers[i];
- u32 phys_base;
-
- if (t->name) {
- t->id = i;
- phys_base = (IS_TIMER1(t->id) ?
- DAVINCI_TIMER1_BASE : DAVINCI_TIMER0_BASE);
- t->base = IO_ADDRESS(phys_base);
-
- if (IS_TIMER_BOT(t->id)) {
- t->enamode_shift = 6;
- t->tim_off = TIM12;
- t->prd_off = PRD12;
- } else {
- t->enamode_shift = 22;
- t->tim_off = TIM34;
- t->prd_off = PRD34;
- }
-
- /* Register interrupt */
- t->irqaction.name = t->name;
- t->irqaction.dev_id = (void *)t;
- if (t->irqaction.handler != NULL) {
- setup_irq(timer_irqs[t->id], &t->irqaction);
- }
-
- timer32_config(&timers[i]);
+ int timer = ID_TO_TIMER(t->id);
+ u32 irq;
+
+ t->base = dtip[timer].base;
+
+ if (IS_TIMER_BOT(t->id)) {
+ t->enamode_shift = 6;
+ t->tim_off = TIM12;
+ t->prd_off = PRD12;
+ irq = dtip[timer].bottom_irq;
+ } else {
+ t->enamode_shift = 22;
+ t->tim_off = TIM34;
+ t->prd_off = PRD34;
+ irq = dtip[timer].top_irq;
}
+
+ /* Register interrupt */
+ t->irqaction.name = t->name;
+ t->irqaction.dev_id = (void *)t;
+ if (t->irqaction.handler != NULL)
+ setup_irq(irq, &t->irqaction);
+
+ timer32_config(&timers[i]);
}
}
@@ -256,7 +242,6 @@ static cycle_t read_cycles(struct clocksource *cs)
}
static struct clocksource clocksource_davinci = {
- .name = "timer0_1",
.rating = 300,
.read = read_cycles,
.mask = CLOCKSOURCE_MASK(32),
@@ -301,7 +286,6 @@ static void davinci_set_mode(enum clock_event_mode mode,
}
static struct clock_event_device clockevent_davinci = {
- .name = "timer0_0",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.shift = 32,
.set_next_event = davinci_set_next_event,
@@ -312,10 +296,14 @@ static struct clock_event_device clockevent_davinci = {
static void __init davinci_timer_init(void)
{
struct clk *timer_clk;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
static char err[] __initdata = KERN_ERR
"%s: can't register clocksource!\n";
+ timers[TID_CLOCKEVENT].id = soc_info->timer_info->clockevent_id;
+ timers[TID_CLOCKSOURCE].id = soc_info->timer_info->clocksource_id;
+
/* init timer hw */
timer_init();
@@ -326,6 +314,7 @@ static void __init davinci_timer_init(void)
davinci_clock_tick_rate = clk_get_rate(timer_clk);
/* setup clocksource */
+ clocksource_davinci.name = id_to_name[timers[TID_CLOCKSOURCE].id];
clocksource_davinci.mult =
clocksource_khz2mult(davinci_clock_tick_rate/1000,
clocksource_davinci.shift);
@@ -333,6 +322,7 @@ static void __init davinci_timer_init(void)
printk(err, clocksource_davinci.name);
/* setup clockevent */
+ clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id];
clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC,
clockevent_davinci.shift);
clockevent_davinci.max_delta_ns =