aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-nomadik
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /arch/arm/plat-nomadik
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'arch/arm/plat-nomadik')
-rw-r--r--arch/arm/plat-nomadik/Kconfig22
-rw-r--r--arch/arm/plat-nomadik/Makefile5
-rw-r--r--arch/arm/plat-nomadik/include/plat/i2c.h37
-rw-r--r--arch/arm/plat-nomadik/include/plat/mtu.h48
-rw-r--r--arch/arm/plat-nomadik/timer.c140
5 files changed, 252 insertions, 0 deletions
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
new file mode 100644
index 000000000000..159daf583f85
--- /dev/null
+++ b/arch/arm/plat-nomadik/Kconfig
@@ -0,0 +1,22 @@
1# We keep common IP's here for Nomadik and other similar
2# familiy of processors from ST-Ericsson. At the moment we have
3# just MTU, others to follow soon.
4
5config PLAT_NOMADIK
6 bool
7 depends on ARCH_NOMADIK || ARCH_U8500
8 default y
9 help
10 Common platform code for Nomadik and other ST-Ericsson
11 platforms.
12
13if PLAT_NOMADIK
14
15config HAS_MTU
16 bool
17 help
18 Support for Multi Timer Unit. MTU provides access
19 to multiple interrupt generating programmable
20 32-bit free running decrementing counters.
21
22endif
diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile
new file mode 100644
index 000000000000..37c7cdd0f8f0
--- /dev/null
+++ b/arch/arm/plat-nomadik/Makefile
@@ -0,0 +1,5 @@
1# arch/arm/plat-nomadik/Makefile
2# Copyright 2009 ST-Ericsson
3# Licensed under GPLv2
4
5obj-$(CONFIG_HAS_MTU) += timer.o
diff --git a/arch/arm/plat-nomadik/include/plat/i2c.h b/arch/arm/plat-nomadik/include/plat/i2c.h
new file mode 100644
index 000000000000..1621db67a53d
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/i2c.h
@@ -0,0 +1,37 @@
1/*
2 * Copyright (C) 2009 ST-Ericsson
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2, as
6 * published by the Free Software Foundation.
7 */
8#ifndef __PLAT_I2C_H
9#define __PLAT_I2C_H
10
11enum i2c_freq_mode {
12 I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */
13 I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */
14 I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */
15 I2C_FREQ_MODE_HIGH_SPEED /* up to 3.4 Mb/s */
16};
17
18/**
19 * struct nmk_i2c_controller - client specific controller configuration
20 * @clk_freq: clock frequency for the operation mode
21 * @slsu: Slave data setup time in ns.
22 * The needed setup time for three modes of operation
23 * are 250ns, 100ns and 10ns respectively thus leading
24 * to the values of 14, 6, 2 for a 48 MHz i2c clk
25 * @tft: Tx FIFO Threshold in bytes
26 * @rft: Rx FIFO Threshold in bytes
27 * @sm: speed mode
28 */
29struct nmk_i2c_controller {
30 unsigned long clk_freq;
31 unsigned short slsu;
32 unsigned char tft;
33 unsigned char rft;
34 enum i2c_freq_mode sm;
35};
36
37#endif /* __PLAT_I2C_H */
diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h
new file mode 100644
index 000000000000..42c907258b14
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/mtu.h
@@ -0,0 +1,48 @@
1#ifndef __PLAT_MTU_H
2#define __PLAT_MTU_H
3
4/* should be set by the platform code */
5extern void __iomem *mtu_base;
6
7/*
8 * The MTU device hosts four different counters, with 4 set of
9 * registers. These are register names.
10 */
11
12#define MTU_IMSC 0x00 /* Interrupt mask set/clear */
13#define MTU_RIS 0x04 /* Raw interrupt status */
14#define MTU_MIS 0x08 /* Masked interrupt status */
15#define MTU_ICR 0x0C /* Interrupt clear register */
16
17/* per-timer registers take 0..3 as argument */
18#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */
19#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */
20#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */
21#define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */
22
23/* bits for the control register */
24#define MTU_CRn_ENA 0x80
25#define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */
26#define MTU_CRn_PRESCALE_MASK 0x0c
27#define MTU_CRn_PRESCALE_1 0x00
28#define MTU_CRn_PRESCALE_16 0x04
29#define MTU_CRn_PRESCALE_256 0x08
30#define MTU_CRn_32BITS 0x02
31#define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/
32
33/* Other registers are usual amba/primecell registers, currently not used */
34#define MTU_ITCR 0xff0
35#define MTU_ITOP 0xff4
36
37#define MTU_PERIPH_ID0 0xfe0
38#define MTU_PERIPH_ID1 0xfe4
39#define MTU_PERIPH_ID2 0xfe8
40#define MTU_PERIPH_ID3 0xfeC
41
42#define MTU_PCELL0 0xff0
43#define MTU_PCELL1 0xff4
44#define MTU_PCELL2 0xff8
45#define MTU_PCELL3 0xffC
46
47#endif /* __PLAT_MTU_H */
48
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
new file mode 100644
index 000000000000..fa7cb3a57cbf
--- /dev/null
+++ b/arch/arm/plat-nomadik/timer.c
@@ -0,0 +1,140 @@
1/*
2 * linux/arch/arm/mach-nomadik/timer.c
3 *
4 * Copyright (C) 2008 STMicroelectronics
5 * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2, as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/interrupt.h>
13#include <linux/irq.h>
14#include <linux/io.h>
15#include <linux/clockchips.h>
16#include <linux/jiffies.h>
17#include <asm/mach/time.h>
18
19#include <plat/mtu.h>
20
21static u32 nmdk_count; /* accumulated count */
22static u32 nmdk_cycle; /* write-once */
23
24/* setup by the platform code */
25void __iomem *mtu_base;
26
27/*
28 * clocksource: the MTU device is a decrementing counters, so we negate
29 * the value being read.
30 */
31static cycle_t nmdk_read_timer(struct clocksource *cs)
32{
33 u32 count = readl(mtu_base + MTU_VAL(0));
34 return nmdk_count + nmdk_cycle - count;
35
36}
37
38static struct clocksource nmdk_clksrc = {
39 .name = "mtu_0",
40 .rating = 120,
41 .read = nmdk_read_timer,
42 .shift = 20,
43 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
44};
45
46/*
47 * Clockevent device: currently only periodic mode is supported
48 */
49static void nmdk_clkevt_mode(enum clock_event_mode mode,
50 struct clock_event_device *dev)
51{
52 switch (mode) {
53 case CLOCK_EVT_MODE_PERIODIC:
54 /* count current value? */
55 writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
56 break;
57 case CLOCK_EVT_MODE_ONESHOT:
58 BUG(); /* Not supported, yet */
59 /* FALLTHROUGH */
60 case CLOCK_EVT_MODE_SHUTDOWN:
61 case CLOCK_EVT_MODE_UNUSED:
62 writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
63 break;
64 case CLOCK_EVT_MODE_RESUME:
65 break;
66 }
67}
68
69static struct clock_event_device nmdk_clkevt = {
70 .name = "mtu_0",
71 .features = CLOCK_EVT_FEAT_PERIODIC,
72 .shift = 32,
73 .rating = 100,
74 .set_mode = nmdk_clkevt_mode,
75};
76
77/*
78 * IRQ Handler for the timer 0 of the MTU block. The irq is not shared
79 * as we are the only users of mtu0 by now.
80 */
81static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
82{
83 /* ack: "interrupt clear register" */
84 writel(1 << 0, mtu_base + MTU_ICR);
85
86 /* we can't count lost ticks, unfortunately */
87 nmdk_count += nmdk_cycle;
88 nmdk_clkevt.event_handler(&nmdk_clkevt);
89
90 return IRQ_HANDLED;
91}
92
93/*
94 * Set up timer interrupt, and return the current time in seconds.
95 */
96static struct irqaction nmdk_timer_irq = {
97 .name = "Nomadik Timer Tick",
98 .flags = IRQF_DISABLED | IRQF_TIMER,
99 .handler = nmdk_timer_interrupt,
100};
101
102static void nmdk_timer_reset(void)
103{
104 u32 cr;
105
106 writel(0, mtu_base + MTU_CR(0)); /* off */
107
108 /* configure load and background-load, and fire it up */
109 writel(nmdk_cycle, mtu_base + MTU_LR(0));
110 writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
111 cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
112 writel(cr, mtu_base + MTU_CR(0));
113 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
114}
115
116void __init nmdk_timer_init(void)
117{
118 unsigned long rate;
119 int bits;
120
121 rate = CLOCK_TICK_RATE; /* 2.4MHz */
122 nmdk_cycle = (rate + HZ/2) / HZ;
123
124 /* Init the timer and register clocksource */
125 nmdk_timer_reset();
126
127 nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
128 bits = 8*sizeof(nmdk_count);
129 nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
130
131 if (clocksource_register(&nmdk_clksrc))
132 printk(KERN_ERR "timer: failed to initialize clock "
133 "source %s\n", nmdk_clksrc.name);
134
135 /* Register irq and clockevents */
136 setup_irq(IRQ_MTU0, &nmdk_timer_irq);
137 nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
138 nmdk_clkevt.cpumask = cpumask_of(0);
139 clockevents_register_device(&nmdk_clkevt);
140}