aboutsummaryrefslogtreecommitdiffstats
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 @@
25#include <mach/mux.h> 25#include <mach/mux.h>
26#include <mach/edma.h> 26#include <mach/edma.h>
27#include <mach/mmc.h> 27#include <mach/mmc.h>
28#include <mach/time.h>
28 29
29#define DAVINCI_I2C_BASE 0x01C21000 30#define DAVINCI_I2C_BASE 0x01C21000
30#define DAVINCI_MMCSD0_BASE 0x01E10000 31#define DAVINCI_MMCSD0_BASE 0x01E10000
@@ -235,6 +236,52 @@ static void davinci_init_wdt(void)
235 236
236/*-------------------------------------------------------------------------*/ 237/*-------------------------------------------------------------------------*/
237 238
239struct davinci_timer_instance davinci_timer_instance[2] = {
240 {
241 .base = IO_ADDRESS(DAVINCI_TIMER0_BASE),
242 .bottom_irq = IRQ_TINT0_TINT12,
243 .top_irq = IRQ_TINT0_TINT34,
244 },
245 {
246 .base = IO_ADDRESS(DAVINCI_TIMER1_BASE),
247 .bottom_irq = IRQ_TINT1_TINT12,
248 .top_irq = IRQ_TINT1_TINT34,
249 },
250};
251
252/*-------------------------------------------------------------------------*/
253
254#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE)
255
256void davinci_init_emac(struct emac_platform_data *pdata)
257{
258 DECLARE_MAC_BUF(buf);
259
260 if (cpu_is_davinci_dm644x())
261 dm644x_init_emac(pdata);
262 else if (cpu_is_davinci_dm646x())
263 dm646x_init_emac(pdata);
264
265 /* if valid MAC exists, don't re-register */
266 if (is_valid_ether_addr(pdata->mac_addr))
267 return;
268 else {
269 /* Use random MAC if none passed */
270 random_ether_addr(pdata->mac_addr);
271
272 printk(KERN_WARNING "%s: using random MAC addr: %s\n",
273 __func__, print_mac(buf, pdata->mac_addr));
274 }
275}
276
277#else
278
279void davinci_init_emac(struct emac_platform_data *unused) {}
280
281#endif
282
283/*-------------------------------------------------------------------------*/
284
238static int __init davinci_init_devices(void) 285static int __init davinci_init_devices(void)
239{ 286{
240 /* please keep these calls, and their implementations above, 287 /* 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 @@
25#include <mach/psc.h> 25#include <mach/psc.h>
26#include <mach/mux.h> 26#include <mach/mux.h>
27#include <mach/irqs.h> 27#include <mach/irqs.h>
28#include <mach/time.h>
28#include <mach/common.h> 29#include <mach/common.h>
29 30
30#include "clock.h" 31#include "clock.h"
@@ -616,6 +617,18 @@ static void __iomem *dm355_psc_bases[] = {
616 IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), 617 IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
617}; 618};
618 619
620/*
621 * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
622 * T0_TOP: Timer 0, top : clocksource for generic timekeeping
623 * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
624 * T1_TOP: Timer 1, top : <unused>
625 */
626struct davinci_timer_info dm355_timer_info = {
627 .timers = davinci_timer_instance,
628 .clockevent_id = T0_BOT,
629 .clocksource_id = T0_TOP,
630};
631
619static struct davinci_soc_info davinci_soc_info_dm355 = { 632static struct davinci_soc_info davinci_soc_info_dm355 = {
620 .io_desc = dm355_io_desc, 633 .io_desc = dm355_io_desc,
621 .io_desc_num = ARRAY_SIZE(dm355_io_desc), 634 .io_desc_num = ARRAY_SIZE(dm355_io_desc),
@@ -632,6 +645,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = {
632 .intc_type = DAVINCI_INTC_TYPE_AINTC, 645 .intc_type = DAVINCI_INTC_TYPE_AINTC,
633 .intc_irq_prios = dm355_default_priorities, 646 .intc_irq_prios = dm355_default_priorities,
634 .intc_irq_num = DAVINCI_N_AINTC_IRQ, 647 .intc_irq_num = DAVINCI_N_AINTC_IRQ,
648 .timer_info = &dm355_timer_info,
635}; 649};
636 650
637void __init dm355_init(void) 651void __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 @@
22#include <mach/irqs.h> 22#include <mach/irqs.h>
23#include <mach/psc.h> 23#include <mach/psc.h>
24#include <mach/mux.h> 24#include <mach/mux.h>
25#include <mach/time.h>
25#include <mach/common.h> 26#include <mach/common.h>
26 27
27#include "clock.h" 28#include "clock.h"
@@ -559,6 +560,18 @@ static void __iomem *dm644x_psc_bases[] = {
559 IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), 560 IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
560}; 561};
561 562
563/*
564 * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
565 * T0_TOP: Timer 0, top : clocksource for generic timekeeping
566 * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
567 * T1_TOP: Timer 1, top : <unused>
568 */
569struct davinci_timer_info dm644x_timer_info = {
570 .timers = davinci_timer_instance,
571 .clockevent_id = T0_BOT,
572 .clocksource_id = T0_TOP,
573};
574
562static struct davinci_soc_info davinci_soc_info_dm644x = { 575static struct davinci_soc_info davinci_soc_info_dm644x = {
563 .io_desc = dm644x_io_desc, 576 .io_desc = dm644x_io_desc,
564 .io_desc_num = ARRAY_SIZE(dm644x_io_desc), 577 .io_desc_num = ARRAY_SIZE(dm644x_io_desc),
@@ -575,6 +588,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
575 .intc_type = DAVINCI_INTC_TYPE_AINTC, 588 .intc_type = DAVINCI_INTC_TYPE_AINTC,
576 .intc_irq_prios = dm644x_default_priorities, 589 .intc_irq_prios = dm644x_default_priorities,
577 .intc_irq_num = DAVINCI_N_AINTC_IRQ, 590 .intc_irq_num = DAVINCI_N_AINTC_IRQ,
591 .timer_info = &dm644x_timer_info,
578}; 592};
579 593
580void __init dm644x_init(void) 594void __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 @@
22#include <mach/irqs.h> 22#include <mach/irqs.h>
23#include <mach/psc.h> 23#include <mach/psc.h>
24#include <mach/mux.h> 24#include <mach/mux.h>
25#include <mach/time.h>
25#include <mach/common.h> 26#include <mach/common.h>
26 27
27#include "clock.h" 28#include "clock.h"
@@ -538,6 +539,18 @@ static void __iomem *dm646x_psc_bases[] = {
538 IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), 539 IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
539}; 540};
540 541
542/*
543 * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
544 * T0_TOP: Timer 0, top : clocksource for generic timekeeping
545 * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
546 * T1_TOP: Timer 1, top : <unused>
547 */
548struct davinci_timer_info dm646x_timer_info = {
549 .timers = davinci_timer_instance,
550 .clockevent_id = T0_BOT,
551 .clocksource_id = T0_TOP,
552};
553
541static struct davinci_soc_info davinci_soc_info_dm646x = { 554static struct davinci_soc_info davinci_soc_info_dm646x = {
542 .io_desc = dm646x_io_desc, 555 .io_desc = dm646x_io_desc,
543 .io_desc_num = ARRAY_SIZE(dm646x_io_desc), 556 .io_desc_num = ARRAY_SIZE(dm646x_io_desc),
@@ -554,6 +567,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = {
554 .intc_type = DAVINCI_INTC_TYPE_AINTC, 567 .intc_type = DAVINCI_INTC_TYPE_AINTC,
555 .intc_irq_prios = dm646x_default_priorities, 568 .intc_irq_prios = dm646x_default_priorities,
556 .intc_irq_num = DAVINCI_N_AINTC_IRQ, 569 .intc_irq_num = DAVINCI_N_AINTC_IRQ,
570 .timer_info = &dm646x_timer_info,
557}; 571};
558 572
559void __init dm646x_init(void) 573void __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);
25/* parameters describe VBUS sourcing for host mode */ 25/* parameters describe VBUS sourcing for host mode */
26extern void setup_usb(unsigned mA, unsigned potpgt_msec); 26extern void setup_usb(unsigned mA, unsigned potpgt_msec);
27 27
28struct davinci_timer_instance {
29 void __iomem *base;
30 u32 bottom_irq;
31 u32 top_irq;
32};
33
34struct davinci_timer_info {
35 struct davinci_timer_instance *timers;
36 unsigned int clockevent_id;
37 unsigned int clocksource_id;
38};
39
28/* SoC specific init support */ 40/* SoC specific init support */
29struct davinci_soc_info { 41struct davinci_soc_info {
30 struct map_desc *io_desc; 42 struct map_desc *io_desc;
@@ -44,6 +56,7 @@ struct davinci_soc_info {
44 int intc_type; 56 int intc_type;
45 u8 *intc_irq_prios; 57 u8 *intc_irq_prios;
46 unsigned long intc_irq_num; 58 unsigned long intc_irq_num;
59 struct davinci_timer_info *timer_info;
47}; 60};
48 61
49extern struct davinci_soc_info davinci_soc_info; 62extern 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 @@
1/*
2 * Local header file for DaVinci time code.
3 *
4 * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
5 *
6 * 2007 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11#ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H
12#define __ARCH_ARM_MACH_DAVINCI_TIME_H
13
14#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
15#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
16
17enum {
18 T0_BOT,
19 T0_TOP,
20 T1_BOT,
21 T1_TOP,
22 NUM_TIMERS
23};
24
25#define IS_TIMER1(id) (id & 0x2)
26#define IS_TIMER0(id) (!IS_TIMER1(id))
27#define IS_TIMER_TOP(id) ((id & 0x1))
28#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id))
29
30#define ID_TO_TIMER(id) (IS_TIMER1(id) != 0)
31
32extern struct davinci_timer_instance davinci_timer_instance[];
33
34#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 @@
29#include <asm/errno.h> 29#include <asm/errno.h>
30#include <mach/io.h> 30#include <mach/io.h>
31#include <mach/cputype.h> 31#include <mach/cputype.h>
32#include <mach/time.h>
32#include "clock.h" 33#include "clock.h"
33 34
34static struct clock_event_device clockevent_davinci; 35static struct clock_event_device clockevent_davinci;
35static unsigned int davinci_clock_tick_rate; 36static unsigned int davinci_clock_tick_rate;
36 37
37#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
38#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
39#define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00) 38#define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00)
40 39
41enum {
42 T0_BOT = 0, T0_TOP, T1_BOT, T1_TOP, NUM_TIMERS,
43};
44
45#define IS_TIMER1(id) (id & 0x2)
46#define IS_TIMER0(id) (!IS_TIMER1(id))
47#define IS_TIMER_TOP(id) ((id & 0x1))
48#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id))
49
50static int timer_irqs[NUM_TIMERS] = {
51 IRQ_TINT0_TINT12,
52 IRQ_TINT0_TINT34,
53 IRQ_TINT1_TINT12,
54 IRQ_TINT1_TINT34,
55};
56
57/* 40/*
58 * This driver configures the 2 64-bit count-up timers as 4 independent 41 * This driver configures the 2 64-bit count-up timers as 4 independent
59 * 32-bit count-up timers used as follows: 42 * 32-bit count-up timers used as follows:
60 *
61 * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
62 * T0_TOP: Timer 0, top : clocksource for generic timekeeping
63 * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
64 * T1_TOP: Timer 1, top : <unused>
65 */ 43 */
66#define TID_CLOCKEVENT T0_BOT 44
67#define TID_CLOCKSOURCE T0_TOP 45enum {
46 TID_CLOCKEVENT,
47 TID_CLOCKSOURCE,
48};
68 49
69/* Timer register offsets */ 50/* Timer register offsets */
70#define PID12 0x0 51#define PID12 0x0
@@ -119,6 +100,13 @@ static struct timer_s timers[];
119#define TIMER_OPTS_ONESHOT 0x01 100#define TIMER_OPTS_ONESHOT 0x01
120#define TIMER_OPTS_PERIODIC 0x02 101#define TIMER_OPTS_PERIODIC 0x02
121 102
103static char *id_to_name[] = {
104 [T0_BOT] = "timer0_0",
105 [T0_TOP] = "timer0_1",
106 [T1_BOT] = "timer1_0",
107 [T1_TOP] = "timer1_1",
108};
109
122static int timer32_config(struct timer_s *t) 110static int timer32_config(struct timer_s *t)
123{ 111{
124 u32 tcr = __raw_readl(t->base + TCR); 112 u32 tcr = __raw_readl(t->base + TCR);
@@ -183,13 +171,14 @@ static struct timer_s timers[] = {
183 171
184static void __init timer_init(void) 172static void __init timer_init(void)
185{ 173{
186 u32 phys_bases[] = {DAVINCI_TIMER0_BASE, DAVINCI_TIMER1_BASE}; 174 struct davinci_soc_info *soc_info = &davinci_soc_info;
175 struct davinci_timer_instance *dtip = soc_info->timer_info->timers;
187 int i; 176 int i;
188 177
189 /* Global init of each 64-bit timer as a whole */ 178 /* Global init of each 64-bit timer as a whole */
190 for(i=0; i<2; i++) { 179 for(i=0; i<2; i++) {
191 u32 tgcr; 180 u32 tgcr;
192 void __iomem *base = IO_ADDRESS(phys_bases[i]); 181 void __iomem *base = dtip[i].base;
193 182
194 /* Disabled, Internal clock source */ 183 /* Disabled, Internal clock source */
195 __raw_writel(0, base + TCR); 184 __raw_writel(0, base + TCR);
@@ -215,33 +204,30 @@ static void __init timer_init(void)
215 /* Init of each timer as a 32-bit timer */ 204 /* Init of each timer as a 32-bit timer */
216 for (i=0; i< ARRAY_SIZE(timers); i++) { 205 for (i=0; i< ARRAY_SIZE(timers); i++) {
217 struct timer_s *t = &timers[i]; 206 struct timer_s *t = &timers[i];
218 u32 phys_base; 207 int timer = ID_TO_TIMER(t->id);
219 208 u32 irq;
220 if (t->name) { 209
221 t->id = i; 210 t->base = dtip[timer].base;
222 phys_base = (IS_TIMER1(t->id) ? 211
223 DAVINCI_TIMER1_BASE : DAVINCI_TIMER0_BASE); 212 if (IS_TIMER_BOT(t->id)) {
224 t->base = IO_ADDRESS(phys_base); 213 t->enamode_shift = 6;
225 214 t->tim_off = TIM12;
226 if (IS_TIMER_BOT(t->id)) { 215 t->prd_off = PRD12;
227 t->enamode_shift = 6; 216 irq = dtip[timer].bottom_irq;
228 t->tim_off = TIM12; 217 } else {
229 t->prd_off = PRD12; 218 t->enamode_shift = 22;
230 } else { 219 t->tim_off = TIM34;
231 t->enamode_shift = 22; 220 t->prd_off = PRD34;
232 t->tim_off = TIM34; 221 irq = dtip[timer].top_irq;
233 t->prd_off = PRD34;
234 }
235
236 /* Register interrupt */
237 t->irqaction.name = t->name;
238 t->irqaction.dev_id = (void *)t;
239 if (t->irqaction.handler != NULL) {
240 setup_irq(timer_irqs[t->id], &t->irqaction);
241 }
242
243 timer32_config(&timers[i]);
244 } 222 }
223
224 /* Register interrupt */
225 t->irqaction.name = t->name;
226 t->irqaction.dev_id = (void *)t;
227 if (t->irqaction.handler != NULL)
228 setup_irq(irq, &t->irqaction);
229
230 timer32_config(&timers[i]);
245 } 231 }
246} 232}
247 233
@@ -256,7 +242,6 @@ static cycle_t read_cycles(struct clocksource *cs)
256} 242}
257 243
258static struct clocksource clocksource_davinci = { 244static struct clocksource clocksource_davinci = {
259 .name = "timer0_1",
260 .rating = 300, 245 .rating = 300,
261 .read = read_cycles, 246 .read = read_cycles,
262 .mask = CLOCKSOURCE_MASK(32), 247 .mask = CLOCKSOURCE_MASK(32),
@@ -301,7 +286,6 @@ static void davinci_set_mode(enum clock_event_mode mode,
301} 286}
302 287
303static struct clock_event_device clockevent_davinci = { 288static struct clock_event_device clockevent_davinci = {
304 .name = "timer0_0",
305 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 289 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
306 .shift = 32, 290 .shift = 32,
307 .set_next_event = davinci_set_next_event, 291 .set_next_event = davinci_set_next_event,
@@ -312,10 +296,14 @@ static struct clock_event_device clockevent_davinci = {
312static void __init davinci_timer_init(void) 296static void __init davinci_timer_init(void)
313{ 297{
314 struct clk *timer_clk; 298 struct clk *timer_clk;
299 struct davinci_soc_info *soc_info = &davinci_soc_info;
315 300
316 static char err[] __initdata = KERN_ERR 301 static char err[] __initdata = KERN_ERR
317 "%s: can't register clocksource!\n"; 302 "%s: can't register clocksource!\n";
318 303
304 timers[TID_CLOCKEVENT].id = soc_info->timer_info->clockevent_id;
305 timers[TID_CLOCKSOURCE].id = soc_info->timer_info->clocksource_id;
306
319 /* init timer hw */ 307 /* init timer hw */
320 timer_init(); 308 timer_init();
321 309
@@ -326,6 +314,7 @@ static void __init davinci_timer_init(void)
326 davinci_clock_tick_rate = clk_get_rate(timer_clk); 314 davinci_clock_tick_rate = clk_get_rate(timer_clk);
327 315
328 /* setup clocksource */ 316 /* setup clocksource */
317 clocksource_davinci.name = id_to_name[timers[TID_CLOCKSOURCE].id];
329 clocksource_davinci.mult = 318 clocksource_davinci.mult =
330 clocksource_khz2mult(davinci_clock_tick_rate/1000, 319 clocksource_khz2mult(davinci_clock_tick_rate/1000,
331 clocksource_davinci.shift); 320 clocksource_davinci.shift);
@@ -333,6 +322,7 @@ static void __init davinci_timer_init(void)
333 printk(err, clocksource_davinci.name); 322 printk(err, clocksource_davinci.name);
334 323
335 /* setup clockevent */ 324 /* setup clockevent */
325 clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id];
336 clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC, 326 clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC,
337 clockevent_davinci.shift); 327 clockevent_davinci.shift);
338 clockevent_davinci.max_delta_ns = 328 clockevent_davinci.max_delta_ns =