aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2010-08-04 09:14:38 -0400
committerJiri Kosina <jkosina@suse.cz>2010-08-04 09:14:38 -0400
commitd790d4d583aeaed9fc6f8a9f4d9f8ce6b1c15c7f (patch)
tree854ab394486288d40fa8179cbfaf66e8bdc44b0f /arch/arm/mach-imx
parent73b2c7165b76b20eb1290e7efebc33cfd21db1ca (diff)
parent3a09b1be53d23df780a0cd0e4087a05e2ca4a00c (diff)
Merge branch 'master' into for-next
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/Kconfig193
-rw-r--r--arch/arm/mach-imx/Makefile33
-rw-r--r--arch/arm/mach-imx/Makefile.boot11
-rw-r--r--arch/arm/mach-imx/clock-imx1.c636
-rw-r--r--arch/arm/mach-imx/clock-imx21.c1239
-rw-r--r--arch/arm/mach-imx/clock-imx27.c763
-rw-r--r--arch/arm/mach-imx/cpu-imx27.c64
-rw-r--r--arch/arm/mach-imx/devices-imx1.h18
-rw-r--r--arch/arm/mach-imx/devices-imx21.h30
-rw-r--r--arch/arm/mach-imx/devices-imx27.h38
-rw-r--r--arch/arm/mach-imx/devices.c609
-rw-r--r--arch/arm/mach-imx/devices.h32
-rw-r--r--arch/arm/mach-imx/dma-v1.c862
-rw-r--r--arch/arm/mach-imx/eukrea_mbimx27-baseboard.c392
-rw-r--r--arch/arm/mach-imx/include/mach/dma-mx1-mx2.h10
-rw-r--r--arch/arm/mach-imx/include/mach/dma-v1.h107
-rw-r--r--arch/arm/mach-imx/mach-cpuimx27.c317
-rw-r--r--arch/arm/mach-imx/mach-imx27lite.c90
-rw-r--r--arch/arm/mach-imx/mach-mx1ads.c165
-rw-r--r--arch/arm/mach-imx/mach-mx21ads.c324
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c119
-rw-r--r--arch/arm/mach-imx/mach-mx27ads.c357
-rw-r--r--arch/arm/mach-imx/mach-mxt_td60.c285
-rw-r--r--arch/arm/mach-imx/mach-pca100.c460
-rw-r--r--arch/arm/mach-imx/mach-pcm038.c352
-rw-r--r--arch/arm/mach-imx/mach-scb9328.c157
-rw-r--r--arch/arm/mach-imx/mm-imx1.c50
-rw-r--r--arch/arm/mach-imx/mm-imx21.c86
-rw-r--r--arch/arm/mach-imx/mm-imx27.c86
-rw-r--r--arch/arm/mach-imx/mx1-camera-fiq-ksym.c18
-rw-r--r--arch/arm/mach-imx/mx1-camera-fiq.S35
-rw-r--r--arch/arm/mach-imx/pcm970-baseboard.c233
-rw-r--r--arch/arm/mach-imx/pm-imx27.c46
33 files changed, 8217 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
new file mode 100644
index 000000000000..c5c0369bb481
--- /dev/null
+++ b/arch/arm/mach-imx/Kconfig
@@ -0,0 +1,193 @@
1config IMX_HAVE_DMA_V1
2 bool
3
4if ARCH_MX1
5
6config SOC_IMX1
7 select CPU_ARM920T
8 select IMX_HAVE_DMA_V1
9 select IMX_HAVE_IOMUX_V1
10 bool
11
12comment "MX1 platforms:"
13config MACH_MXLADS
14 bool
15
16config ARCH_MX1ADS
17 bool "MX1ADS platform"
18 select MACH_MXLADS
19 select IMX_HAVE_PLATFORM_IMX_I2C
20 select IMX_HAVE_PLATFORM_IMX_UART
21 help
22 Say Y here if you are using Motorola MX1ADS/MXLADS boards
23
24config MACH_SCB9328
25 bool "Synertronixx scb9328"
26 select IMX_HAVE_PLATFORM_IMX_UART
27 help
28 Say Y here if you are using a Synertronixx scb9328 board
29
30endif
31
32if ARCH_MX2
33
34config SOC_IMX21
35 select CPU_ARM926T
36 select ARCH_MXC_AUDMUX_V1
37 select IMX_HAVE_DMA_V1
38 select IMX_HAVE_IOMUX_V1
39 bool
40
41config SOC_IMX27
42 select CPU_ARM926T
43 select ARCH_MXC_AUDMUX_V1
44 select IMX_HAVE_DMA_V1
45 select IMX_HAVE_IOMUX_V1
46 bool
47
48choice
49 prompt "CPUs:"
50 default MACH_MX21
51
52config MACH_MX21
53 bool "i.MX21 support"
54 select SOC_IMX21
55 help
56 This enables support for Freescale's MX2 based i.MX21 processor.
57
58config MACH_MX27
59 bool "i.MX27 support"
60 select SOC_IMX27
61 help
62 This enables support for Freescale's MX2 based i.MX27 processor.
63
64endchoice
65
66endif
67
68if MACH_MX21
69
70comment "MX21 platforms:"
71
72config MACH_MX21ADS
73 bool "MX21ADS platform"
74 select IMX_HAVE_PLATFORM_IMX_UART
75 select IMX_HAVE_PLATFORM_MXC_NAND
76 help
77 Include support for MX21ADS platform. This includes specific
78 configurations for the board and its peripherals.
79
80endif
81
82if MACH_MX27
83
84comment "MX27 platforms:"
85
86config MACH_MX27ADS
87 bool "MX27ADS platform"
88 select IMX_HAVE_PLATFORM_IMX_I2C
89 select IMX_HAVE_PLATFORM_IMX_UART
90 select IMX_HAVE_PLATFORM_MXC_NAND
91 help
92 Include support for MX27ADS platform. This includes specific
93 configurations for the board and its peripherals.
94
95config MACH_PCM038
96 bool "Phytec phyCORE-i.MX27 CPU module (pcm038)"
97 select IMX_HAVE_PLATFORM_IMX_I2C
98 select IMX_HAVE_PLATFORM_IMX_UART
99 select IMX_HAVE_PLATFORM_MXC_NAND
100 select IMX_HAVE_PLATFORM_SPI_IMX
101 select MXC_ULPI if USB_ULPI
102 help
103 Include support for phyCORE-i.MX27 (aka pcm038) platform. This
104 includes specific configurations for the module and its peripherals.
105
106choice
107 prompt "Baseboard"
108 depends on MACH_PCM038
109 default MACH_PCM970_BASEBOARD
110
111config MACH_PCM970_BASEBOARD
112 prompt "PHYTEC PCM970 development board"
113 bool
114 help
115 This adds board specific devices that can be found on Phytec's
116 PCM970 evaluation board.
117
118endchoice
119
120config MACH_CPUIMX27
121 bool "Eukrea CPUIMX27 module"
122 select IMX_HAVE_PLATFORM_IMX_I2C
123 select IMX_HAVE_PLATFORM_IMX_UART
124 select IMX_HAVE_PLATFORM_MXC_NAND
125 help
126 Include support for Eukrea CPUIMX27 platform. This includes
127 specific configurations for the module and its peripherals.
128
129config MACH_EUKREA_CPUIMX27_USESDHC2
130 bool "CPUIMX27 integrates SDHC2 module"
131 depends on MACH_CPUIMX27
132 help
133 This adds support for the internal SDHC2 used on CPUIMX27
134 for wifi or eMMC.
135
136config MACH_EUKREA_CPUIMX27_USEUART4
137 bool "CPUIMX27 integrates UART4 module"
138 depends on MACH_CPUIMX27
139 help
140 This adds support for the internal UART4 used on CPUIMX27
141 for bluetooth.
142
143choice
144 prompt "Baseboard"
145 depends on MACH_CPUIMX27
146 default MACH_EUKREA_MBIMX27_BASEBOARD
147
148config MACH_EUKREA_MBIMX27_BASEBOARD
149 prompt "Eukrea MBIMX27 development board"
150 bool
151 select IMX_HAVE_PLATFORM_IMX_UART
152 select IMX_HAVE_PLATFORM_SPI_IMX
153 help
154 This adds board specific devices that can be found on Eukrea's
155 MBIMX27 evaluation board.
156
157endchoice
158
159config MACH_MX27_3DS
160 bool "MX27PDK platform"
161 select IMX_HAVE_PLATFORM_IMX_UART
162 help
163 Include support for MX27PDK platform. This includes specific
164 configurations for the board and its peripherals.
165
166config MACH_IMX27LITE
167 bool "LogicPD MX27 LITEKIT platform"
168 select IMX_HAVE_PLATFORM_IMX_UART
169 help
170 Include support for MX27 LITEKIT platform. This includes specific
171 configurations for the board and its peripherals.
172
173config MACH_PCA100
174 bool "Phytec phyCARD-s (pca100)"
175 select IMX_HAVE_PLATFORM_IMX_I2C
176 select IMX_HAVE_PLATFORM_IMX_UART
177 select IMX_HAVE_PLATFORM_MXC_NAND
178 select IMX_HAVE_PLATFORM_SPI_IMX
179 select MXC_ULPI if USB_ULPI
180 help
181 Include support for phyCARD-s (aka pca100) platform. This
182 includes specific configurations for the module and its peripherals.
183
184config MACH_MXT_TD60
185 bool "Maxtrack i-MXT TD60"
186 select IMX_HAVE_PLATFORM_IMX_I2C
187 select IMX_HAVE_PLATFORM_IMX_UART
188 select IMX_HAVE_PLATFORM_MXC_NAND
189 help
190 Include support for i-MXT (aka td60) platform. This
191 includes specific configurations for the module and its peripherals.
192
193endif
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
new file mode 100644
index 000000000000..46a9fdfbbd15
--- /dev/null
+++ b/arch/arm/mach-imx/Makefile
@@ -0,0 +1,33 @@
1#
2# Makefile for the linux kernel.
3#
4
5# Object file lists.
6
7obj-y := devices.o
8
9obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o
10
11obj-$(CONFIG_ARCH_MX1) += clock-imx1.o mm-imx1.o
12obj-$(CONFIG_MACH_MX21) += clock-imx21.o mm-imx21.o
13
14obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o
15obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o
16
17# Support for CMOS sensor interface
18obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
19
20obj-$(CONFIG_ARCH_MX1ADS) += mach-mx1ads.o
21obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o
22
23obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o
24
25obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
26obj-$(CONFIG_MACH_PCM038) += mach-pcm038.o
27obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
28obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o
29obj-$(CONFIG_MACH_IMX27LITE) += mach-imx27lite.o
30obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o
31obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
32obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
33obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
new file mode 100644
index 000000000000..7988a85cf07d
--- /dev/null
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -0,0 +1,11 @@
1zreladdr-$(CONFIG_ARCH_MX1) := 0x08008000
2params_phys-$(CONFIG_ARCH_MX1) := 0x08000100
3initrd_phys-$(CONFIG_ARCH_MX1) := 0x08800000
4
5zreladdr-$(CONFIG_MACH_MX21) := 0xC0008000
6params_phys-$(CONFIG_MACH_MX21) := 0xC0000100
7initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
8
9zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000
10params_phys-$(CONFIG_MACH_MX27) := 0xA0000100
11initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c
new file mode 100644
index 000000000000..c05096c38301
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx1.c
@@ -0,0 +1,636 @@
1/*
2 * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
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 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/list.h>
21#include <linux/math64.h>
22#include <linux/err.h>
23#include <linux/clk.h>
24#include <linux/io.h>
25
26#include <asm/clkdev.h>
27
28#include <mach/clock.h>
29#include <mach/hardware.h>
30#include <mach/common.h>
31
32#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
33
34/* CCM register addresses */
35#define CCM_CSCR IO_ADDR_CCM(0x0)
36#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
37#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
38#define CCM_PCDR IO_ADDR_CCM(0x20)
39
40#define CCM_CSCR_CLKO_OFFSET 29
41#define CCM_CSCR_CLKO_MASK (0x7 << 29)
42#define CCM_CSCR_USB_OFFSET 26
43#define CCM_CSCR_USB_MASK (0x7 << 26)
44#define CCM_CSCR_OSC_EN_SHIFT 17
45#define CCM_CSCR_SYSTEM_SEL (1 << 16)
46#define CCM_CSCR_BCLK_OFFSET 10
47#define CCM_CSCR_BCLK_MASK (0xf << 10)
48#define CCM_CSCR_PRESC (1 << 15)
49
50#define CCM_PCDR_PCLK3_OFFSET 16
51#define CCM_PCDR_PCLK3_MASK (0x7f << 16)
52#define CCM_PCDR_PCLK2_OFFSET 4
53#define CCM_PCDR_PCLK2_MASK (0xf << 4)
54#define CCM_PCDR_PCLK1_OFFSET 0
55#define CCM_PCDR_PCLK1_MASK 0xf
56
57#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
58
59/* SCM register addresses */
60#define SCM_GCCR IO_ADDR_SCM(0xc)
61
62#define SCM_GCCR_DMA_CLK_EN_OFFSET 3
63#define SCM_GCCR_CSI_CLK_EN_OFFSET 2
64#define SCM_GCCR_MMA_CLK_EN_OFFSET 1
65#define SCM_GCCR_USBD_CLK_EN_OFFSET 0
66
67static int _clk_enable(struct clk *clk)
68{
69 unsigned int reg;
70
71 reg = __raw_readl(clk->enable_reg);
72 reg |= 1 << clk->enable_shift;
73 __raw_writel(reg, clk->enable_reg);
74
75 return 0;
76}
77
78static void _clk_disable(struct clk *clk)
79{
80 unsigned int reg;
81
82 reg = __raw_readl(clk->enable_reg);
83 reg &= ~(1 << clk->enable_shift);
84 __raw_writel(reg, clk->enable_reg);
85}
86
87static int _clk_can_use_parent(const struct clk *clk_arr[], unsigned int size,
88 struct clk *parent)
89{
90 int i;
91
92 for (i = 0; i < size; i++)
93 if (parent == clk_arr[i])
94 return i;
95
96 return -EINVAL;
97}
98
99static unsigned long
100_clk_simple_round_rate(struct clk *clk, unsigned long rate, unsigned int limit)
101{
102 int div;
103 unsigned long parent_rate;
104
105 parent_rate = clk_get_rate(clk->parent);
106
107 div = parent_rate / rate;
108 if (parent_rate % rate)
109 div++;
110
111 if (div > limit)
112 div = limit;
113
114 return parent_rate / div;
115}
116
117static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
118{
119 return clk->parent->round_rate(clk->parent, rate);
120}
121
122static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
123{
124 return clk->parent->set_rate(clk->parent, rate);
125}
126
127static unsigned long clk16m_get_rate(struct clk *clk)
128{
129 return 16000000;
130}
131
132static struct clk clk16m = {
133 .get_rate = clk16m_get_rate,
134 .enable = _clk_enable,
135 .enable_reg = CCM_CSCR,
136 .enable_shift = CCM_CSCR_OSC_EN_SHIFT,
137 .disable = _clk_disable,
138};
139
140/* in Hz */
141static unsigned long clk32_rate;
142
143static unsigned long clk32_get_rate(struct clk *clk)
144{
145 return clk32_rate;
146}
147
148static struct clk clk32 = {
149 .get_rate = clk32_get_rate,
150};
151
152static unsigned long clk32_premult_get_rate(struct clk *clk)
153{
154 return clk_get_rate(clk->parent) * 512;
155}
156
157static struct clk clk32_premult = {
158 .parent = &clk32,
159 .get_rate = clk32_premult_get_rate,
160};
161
162static const struct clk *prem_clk_clocks[] = {
163 &clk32_premult,
164 &clk16m,
165};
166
167static int prem_clk_set_parent(struct clk *clk, struct clk *parent)
168{
169 int i;
170 unsigned int reg = __raw_readl(CCM_CSCR);
171
172 i = _clk_can_use_parent(prem_clk_clocks, ARRAY_SIZE(prem_clk_clocks),
173 parent);
174
175 switch (i) {
176 case 0:
177 reg &= ~CCM_CSCR_SYSTEM_SEL;
178 break;
179 case 1:
180 reg |= CCM_CSCR_SYSTEM_SEL;
181 break;
182 default:
183 return i;
184 }
185
186 __raw_writel(reg, CCM_CSCR);
187
188 return 0;
189}
190
191static struct clk prem_clk = {
192 .set_parent = prem_clk_set_parent,
193};
194
195static unsigned long system_clk_get_rate(struct clk *clk)
196{
197 return mxc_decode_pll(__raw_readl(CCM_SPCTL0),
198 clk_get_rate(clk->parent));
199}
200
201static struct clk system_clk = {
202 .parent = &prem_clk,
203 .get_rate = system_clk_get_rate,
204};
205
206static unsigned long mcu_clk_get_rate(struct clk *clk)
207{
208 return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
209 clk_get_rate(clk->parent));
210}
211
212static struct clk mcu_clk = {
213 .parent = &clk32_premult,
214 .get_rate = mcu_clk_get_rate,
215};
216
217static unsigned long fclk_get_rate(struct clk *clk)
218{
219 unsigned long fclk = clk_get_rate(clk->parent);
220
221 if (__raw_readl(CCM_CSCR) & CCM_CSCR_PRESC)
222 fclk /= 2;
223
224 return fclk;
225}
226
227static struct clk fclk = {
228 .parent = &mcu_clk,
229 .get_rate = fclk_get_rate,
230};
231
232/*
233 * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA )
234 */
235static unsigned long hclk_get_rate(struct clk *clk)
236{
237 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) &
238 CCM_CSCR_BCLK_MASK) >> CCM_CSCR_BCLK_OFFSET) + 1);
239}
240
241static unsigned long hclk_round_rate(struct clk *clk, unsigned long rate)
242{
243 return _clk_simple_round_rate(clk, rate, 16);
244}
245
246static int hclk_set_rate(struct clk *clk, unsigned long rate)
247{
248 unsigned int div;
249 unsigned int reg;
250 unsigned long parent_rate;
251
252 parent_rate = clk_get_rate(clk->parent);
253
254 div = parent_rate / rate;
255
256 if (div > 16 || div < 1 || ((parent_rate / div) != rate))
257 return -EINVAL;
258
259 div--;
260
261 reg = __raw_readl(CCM_CSCR);
262 reg &= ~CCM_CSCR_BCLK_MASK;
263 reg |= div << CCM_CSCR_BCLK_OFFSET;
264 __raw_writel(reg, CCM_CSCR);
265
266 return 0;
267}
268
269static struct clk hclk = {
270 .parent = &system_clk,
271 .get_rate = hclk_get_rate,
272 .round_rate = hclk_round_rate,
273 .set_rate = hclk_set_rate,
274};
275
276static unsigned long clk48m_get_rate(struct clk *clk)
277{
278 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) &
279 CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET) + 1);
280}
281
282static unsigned long clk48m_round_rate(struct clk *clk, unsigned long rate)
283{
284 return _clk_simple_round_rate(clk, rate, 8);
285}
286
287static int clk48m_set_rate(struct clk *clk, unsigned long rate)
288{
289 unsigned int div;
290 unsigned int reg;
291 unsigned long parent_rate;
292
293 parent_rate = clk_get_rate(clk->parent);
294
295 div = parent_rate / rate;
296
297 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
298 return -EINVAL;
299
300 div--;
301
302 reg = __raw_readl(CCM_CSCR);
303 reg &= ~CCM_CSCR_USB_MASK;
304 reg |= div << CCM_CSCR_USB_OFFSET;
305 __raw_writel(reg, CCM_CSCR);
306
307 return 0;
308}
309
310static struct clk clk48m = {
311 .parent = &system_clk,
312 .get_rate = clk48m_get_rate,
313 .round_rate = clk48m_round_rate,
314 .set_rate = clk48m_set_rate,
315};
316
317/*
318 * get peripheral clock 1 ( UART[12], Timer[12], PWM )
319 */
320static unsigned long perclk1_get_rate(struct clk *clk)
321{
322 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
323 CCM_PCDR_PCLK1_MASK) >> CCM_PCDR_PCLK1_OFFSET) + 1);
324}
325
326static unsigned long perclk1_round_rate(struct clk *clk, unsigned long rate)
327{
328 return _clk_simple_round_rate(clk, rate, 16);
329}
330
331static int perclk1_set_rate(struct clk *clk, unsigned long rate)
332{
333 unsigned int div;
334 unsigned int reg;
335 unsigned long parent_rate;
336
337 parent_rate = clk_get_rate(clk->parent);
338
339 div = parent_rate / rate;
340
341 if (div > 16 || div < 1 || ((parent_rate / div) != rate))
342 return -EINVAL;
343
344 div--;
345
346 reg = __raw_readl(CCM_PCDR);
347 reg &= ~CCM_PCDR_PCLK1_MASK;
348 reg |= div << CCM_PCDR_PCLK1_OFFSET;
349 __raw_writel(reg, CCM_PCDR);
350
351 return 0;
352}
353
354/*
355 * get peripheral clock 2 ( LCD, SD, SPI[12] )
356 */
357static unsigned long perclk2_get_rate(struct clk *clk)
358{
359 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
360 CCM_PCDR_PCLK2_MASK) >> CCM_PCDR_PCLK2_OFFSET) + 1);
361}
362
363static unsigned long perclk2_round_rate(struct clk *clk, unsigned long rate)
364{
365 return _clk_simple_round_rate(clk, rate, 16);
366}
367
368static int perclk2_set_rate(struct clk *clk, unsigned long rate)
369{
370 unsigned int div;
371 unsigned int reg;
372 unsigned long parent_rate;
373
374 parent_rate = clk_get_rate(clk->parent);
375
376 div = parent_rate / rate;
377
378 if (div > 16 || div < 1 || ((parent_rate / div) != rate))
379 return -EINVAL;
380
381 div--;
382
383 reg = __raw_readl(CCM_PCDR);
384 reg &= ~CCM_PCDR_PCLK2_MASK;
385 reg |= div << CCM_PCDR_PCLK2_OFFSET;
386 __raw_writel(reg, CCM_PCDR);
387
388 return 0;
389}
390
391/*
392 * get peripheral clock 3 ( SSI )
393 */
394static unsigned long perclk3_get_rate(struct clk *clk)
395{
396 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
397 CCM_PCDR_PCLK3_MASK) >> CCM_PCDR_PCLK3_OFFSET) + 1);
398}
399
400static unsigned long perclk3_round_rate(struct clk *clk, unsigned long rate)
401{
402 return _clk_simple_round_rate(clk, rate, 128);
403}
404
405static int perclk3_set_rate(struct clk *clk, unsigned long rate)
406{
407 unsigned int div;
408 unsigned int reg;
409 unsigned long parent_rate;
410
411 parent_rate = clk_get_rate(clk->parent);
412
413 div = parent_rate / rate;
414
415 if (div > 128 || div < 1 || ((parent_rate / div) != rate))
416 return -EINVAL;
417
418 div--;
419
420 reg = __raw_readl(CCM_PCDR);
421 reg &= ~CCM_PCDR_PCLK3_MASK;
422 reg |= div << CCM_PCDR_PCLK3_OFFSET;
423 __raw_writel(reg, CCM_PCDR);
424
425 return 0;
426}
427
428static struct clk perclk[] = {
429 {
430 .id = 0,
431 .parent = &system_clk,
432 .get_rate = perclk1_get_rate,
433 .round_rate = perclk1_round_rate,
434 .set_rate = perclk1_set_rate,
435 }, {
436 .id = 1,
437 .parent = &system_clk,
438 .get_rate = perclk2_get_rate,
439 .round_rate = perclk2_round_rate,
440 .set_rate = perclk2_set_rate,
441 }, {
442 .id = 2,
443 .parent = &system_clk,
444 .get_rate = perclk3_get_rate,
445 .round_rate = perclk3_round_rate,
446 .set_rate = perclk3_set_rate,
447 }
448};
449
450static const struct clk *clko_clocks[] = {
451 &perclk[0],
452 &hclk,
453 &clk48m,
454 &clk16m,
455 &prem_clk,
456 &fclk,
457};
458
459static int clko_set_parent(struct clk *clk, struct clk *parent)
460{
461 int i;
462 unsigned int reg;
463
464 i = _clk_can_use_parent(clko_clocks, ARRAY_SIZE(clko_clocks), parent);
465 if (i < 0)
466 return i;
467
468 reg = __raw_readl(CCM_CSCR) & ~CCM_CSCR_CLKO_MASK;
469 reg |= i << CCM_CSCR_CLKO_OFFSET;
470 __raw_writel(reg, CCM_CSCR);
471
472 if (clko_clocks[i]->set_rate && clko_clocks[i]->round_rate) {
473 clk->set_rate = _clk_parent_set_rate;
474 clk->round_rate = _clk_parent_round_rate;
475 } else {
476 clk->set_rate = NULL;
477 clk->round_rate = NULL;
478 }
479
480 return 0;
481}
482
483static struct clk clko_clk = {
484 .set_parent = clko_set_parent,
485};
486
487static struct clk dma_clk = {
488 .parent = &hclk,
489 .round_rate = _clk_parent_round_rate,
490 .set_rate = _clk_parent_set_rate,
491 .enable = _clk_enable,
492 .enable_reg = SCM_GCCR,
493 .enable_shift = SCM_GCCR_DMA_CLK_EN_OFFSET,
494 .disable = _clk_disable,
495};
496
497static struct clk csi_clk = {
498 .parent = &hclk,
499 .round_rate = _clk_parent_round_rate,
500 .set_rate = _clk_parent_set_rate,
501 .enable = _clk_enable,
502 .enable_reg = SCM_GCCR,
503 .enable_shift = SCM_GCCR_CSI_CLK_EN_OFFSET,
504 .disable = _clk_disable,
505};
506
507static struct clk mma_clk = {
508 .parent = &hclk,
509 .round_rate = _clk_parent_round_rate,
510 .set_rate = _clk_parent_set_rate,
511 .enable = _clk_enable,
512 .enable_reg = SCM_GCCR,
513 .enable_shift = SCM_GCCR_MMA_CLK_EN_OFFSET,
514 .disable = _clk_disable,
515};
516
517static struct clk usbd_clk = {
518 .parent = &clk48m,
519 .round_rate = _clk_parent_round_rate,
520 .set_rate = _clk_parent_set_rate,
521 .enable = _clk_enable,
522 .enable_reg = SCM_GCCR,
523 .enable_shift = SCM_GCCR_USBD_CLK_EN_OFFSET,
524 .disable = _clk_disable,
525};
526
527static struct clk gpt_clk = {
528 .parent = &perclk[0],
529 .round_rate = _clk_parent_round_rate,
530 .set_rate = _clk_parent_set_rate,
531};
532
533static struct clk uart_clk = {
534 .parent = &perclk[0],
535 .round_rate = _clk_parent_round_rate,
536 .set_rate = _clk_parent_set_rate,
537};
538
539static struct clk i2c_clk = {
540 .parent = &hclk,
541 .round_rate = _clk_parent_round_rate,
542 .set_rate = _clk_parent_set_rate,
543};
544
545static struct clk spi_clk = {
546 .parent = &perclk[1],
547 .round_rate = _clk_parent_round_rate,
548 .set_rate = _clk_parent_set_rate,
549};
550
551static struct clk sdhc_clk = {
552 .parent = &perclk[1],
553 .round_rate = _clk_parent_round_rate,
554 .set_rate = _clk_parent_set_rate,
555};
556
557static struct clk lcdc_clk = {
558 .parent = &perclk[1],
559 .round_rate = _clk_parent_round_rate,
560 .set_rate = _clk_parent_set_rate,
561};
562
563static struct clk mshc_clk = {
564 .parent = &hclk,
565 .round_rate = _clk_parent_round_rate,
566 .set_rate = _clk_parent_set_rate,
567};
568
569static struct clk ssi_clk = {
570 .parent = &perclk[2],
571 .round_rate = _clk_parent_round_rate,
572 .set_rate = _clk_parent_set_rate,
573};
574
575static struct clk rtc_clk = {
576 .parent = &clk32,
577};
578
579#define _REGISTER_CLOCK(d, n, c) \
580 { \
581 .dev_id = d, \
582 .con_id = n, \
583 .clk = &c, \
584 },
585static struct clk_lookup lookups[] __initdata = {
586 _REGISTER_CLOCK(NULL, "dma", dma_clk)
587 _REGISTER_CLOCK("mx1-camera.0", NULL, csi_clk)
588 _REGISTER_CLOCK(NULL, "mma", mma_clk)
589 _REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk)
590 _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
591 _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk)
592 _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk)
593 _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk)
594 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
595 _REGISTER_CLOCK("spi_imx.0", NULL, spi_clk)
596 _REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk)
597 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
598 _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
599 _REGISTER_CLOCK(NULL, "ssi", ssi_clk)
600 _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk)
601};
602
603int __init mx1_clocks_init(unsigned long fref)
604{
605 unsigned int reg;
606
607 /* disable clocks we are able to */
608 __raw_writel(0, SCM_GCCR);
609
610 clk32_rate = fref;
611 reg = __raw_readl(CCM_CSCR);
612
613 /* detect clock reference for system PLL */
614 if (reg & CCM_CSCR_SYSTEM_SEL) {
615 prem_clk.parent = &clk16m;
616 } else {
617 /* ensure that oscillator is disabled */
618 reg &= ~(1 << CCM_CSCR_OSC_EN_SHIFT);
619 __raw_writel(reg, CCM_CSCR);
620 prem_clk.parent = &clk32_premult;
621 }
622
623 /* detect reference for CLKO */
624 reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET;
625 clko_clk.parent = (struct clk *)clko_clocks[reg];
626
627 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
628
629 clk_enable(&hclk);
630 clk_enable(&fclk);
631
632 mxc_timer_init(&gpt_clk, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
633 MX1_TIM1_INT);
634
635 return 0;
636}
diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c
new file mode 100644
index 000000000000..bb419ef4d133
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx21.c
@@ -0,0 +1,1239 @@
1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <linux/clk.h>
22#include <linux/io.h>
23#include <linux/module.h>
24
25#include <mach/clock.h>
26#include <mach/hardware.h>
27#include <mach/common.h>
28#include <asm/clkdev.h>
29#include <asm/div64.h>
30
31#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
32
33/* Register offsets */
34#define CCM_CSCR IO_ADDR_CCM(0x0)
35#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
36#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
37#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
38#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
39#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
40#define CCM_PCDR0 IO_ADDR_CCM(0x18)
41#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
42#define CCM_PCCR0 IO_ADDR_CCM(0x20)
43#define CCM_PCCR1 IO_ADDR_CCM(0x24)
44#define CCM_CCSR IO_ADDR_CCM(0x28)
45#define CCM_PMCTL IO_ADDR_CCM(0x2c)
46#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
47#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
48
49#define CCM_CSCR_PRESC_OFFSET 29
50#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
51
52#define CCM_CSCR_USB_OFFSET 26
53#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET)
54#define CCM_CSCR_SD_OFFSET 24
55#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET)
56#define CCM_CSCR_SPLLRES (1 << 22)
57#define CCM_CSCR_MPLLRES (1 << 21)
58#define CCM_CSCR_SSI2_OFFSET 20
59#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET)
60#define CCM_CSCR_SSI1_OFFSET 19
61#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET)
62#define CCM_CSCR_FIR_OFFSET 18
63#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET)
64#define CCM_CSCR_SP (1 << 17)
65#define CCM_CSCR_MCU (1 << 16)
66#define CCM_CSCR_BCLK_OFFSET 10
67#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET)
68#define CCM_CSCR_IPDIV_OFFSET 9
69#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET)
70
71#define CCM_CSCR_OSC26MDIV (1 << 4)
72#define CCM_CSCR_OSC26M (1 << 3)
73#define CCM_CSCR_FPM (1 << 2)
74#define CCM_CSCR_SPEN (1 << 1)
75#define CCM_CSCR_MPEN 1
76
77#define CCM_MPCTL0_CPLM (1 << 31)
78#define CCM_MPCTL0_PD_OFFSET 26
79#define CCM_MPCTL0_PD_MASK (0xf << 26)
80#define CCM_MPCTL0_MFD_OFFSET 16
81#define CCM_MPCTL0_MFD_MASK (0x3ff << 16)
82#define CCM_MPCTL0_MFI_OFFSET 10
83#define CCM_MPCTL0_MFI_MASK (0xf << 10)
84#define CCM_MPCTL0_MFN_OFFSET 0
85#define CCM_MPCTL0_MFN_MASK 0x3ff
86
87#define CCM_MPCTL1_LF (1 << 15)
88#define CCM_MPCTL1_BRMO (1 << 6)
89
90#define CCM_SPCTL0_CPLM (1 << 31)
91#define CCM_SPCTL0_PD_OFFSET 26
92#define CCM_SPCTL0_PD_MASK (0xf << 26)
93#define CCM_SPCTL0_MFD_OFFSET 16
94#define CCM_SPCTL0_MFD_MASK (0x3ff << 16)
95#define CCM_SPCTL0_MFI_OFFSET 10
96#define CCM_SPCTL0_MFI_MASK (0xf << 10)
97#define CCM_SPCTL0_MFN_OFFSET 0
98#define CCM_SPCTL0_MFN_MASK 0x3ff
99
100#define CCM_SPCTL1_LF (1 << 15)
101#define CCM_SPCTL1_BRMO (1 << 6)
102
103#define CCM_OSC26MCTL_PEAK_OFFSET 16
104#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16)
105#define CCM_OSC26MCTL_AGC_OFFSET 8
106#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8)
107#define CCM_OSC26MCTL_ANATEST_OFFSET 0
108#define CCM_OSC26MCTL_ANATEST_MASK 0x3f
109
110#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
111#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
112#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
113#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
114#define CCM_PCDR0_NFCDIV_OFFSET 12
115#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
116#define CCM_PCDR0_48MDIV_OFFSET 5
117#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET)
118#define CCM_PCDR0_FIRIDIV_OFFSET 0
119#define CCM_PCDR0_FIRIDIV_MASK 0x1f
120#define CCM_PCDR1_PERDIV4_OFFSET 24
121#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
122#define CCM_PCDR1_PERDIV3_OFFSET 16
123#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16)
124#define CCM_PCDR1_PERDIV2_OFFSET 8
125#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8)
126#define CCM_PCDR1_PERDIV1_OFFSET 0
127#define CCM_PCDR1_PERDIV1_MASK 0x3f
128
129#define CCM_PCCR_HCLK_CSI_OFFSET 31
130#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0
131#define CCM_PCCR_HCLK_DMA_OFFSET 30
132#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0
133#define CCM_PCCR_HCLK_BROM_OFFSET 28
134#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0
135#define CCM_PCCR_HCLK_EMMA_OFFSET 27
136#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0
137#define CCM_PCCR_HCLK_LCDC_OFFSET 26
138#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0
139#define CCM_PCCR_HCLK_SLCDC_OFFSET 25
140#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0
141#define CCM_PCCR_HCLK_USBOTG_OFFSET 24
142#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0
143#define CCM_PCCR_HCLK_BMI_OFFSET 23
144#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK)
145#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0
146#define CCM_PCCR_PERCLK4_OFFSET 22
147#define CCM_PCCR_PERCLK4_REG CCM_PCCR0
148#define CCM_PCCR_SLCDC_OFFSET 21
149#define CCM_PCCR_SLCDC_REG CCM_PCCR0
150#define CCM_PCCR_FIRI_BAUD_OFFSET 20
151#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK)
152#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0
153#define CCM_PCCR_NFC_OFFSET 19
154#define CCM_PCCR_NFC_REG CCM_PCCR0
155#define CCM_PCCR_LCDC_OFFSET 18
156#define CCM_PCCR_LCDC_REG CCM_PCCR0
157#define CCM_PCCR_SSI1_BAUD_OFFSET 17
158#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0
159#define CCM_PCCR_SSI2_BAUD_OFFSET 16
160#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0
161#define CCM_PCCR_EMMA_OFFSET 15
162#define CCM_PCCR_EMMA_REG CCM_PCCR0
163#define CCM_PCCR_USBOTG_OFFSET 14
164#define CCM_PCCR_USBOTG_REG CCM_PCCR0
165#define CCM_PCCR_DMA_OFFSET 13
166#define CCM_PCCR_DMA_REG CCM_PCCR0
167#define CCM_PCCR_I2C1_OFFSET 12
168#define CCM_PCCR_I2C1_REG CCM_PCCR0
169#define CCM_PCCR_GPIO_OFFSET 11
170#define CCM_PCCR_GPIO_REG CCM_PCCR0
171#define CCM_PCCR_SDHC2_OFFSET 10
172#define CCM_PCCR_SDHC2_REG CCM_PCCR0
173#define CCM_PCCR_SDHC1_OFFSET 9
174#define CCM_PCCR_SDHC1_REG CCM_PCCR0
175#define CCM_PCCR_FIRI_OFFSET 8
176#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK)
177#define CCM_PCCR_FIRI_REG CCM_PCCR0
178#define CCM_PCCR_SSI2_IPG_OFFSET 7
179#define CCM_PCCR_SSI2_REG CCM_PCCR0
180#define CCM_PCCR_SSI1_IPG_OFFSET 6
181#define CCM_PCCR_SSI1_REG CCM_PCCR0
182#define CCM_PCCR_CSPI2_OFFSET 5
183#define CCM_PCCR_CSPI2_REG CCM_PCCR0
184#define CCM_PCCR_CSPI1_OFFSET 4
185#define CCM_PCCR_CSPI1_REG CCM_PCCR0
186#define CCM_PCCR_UART4_OFFSET 3
187#define CCM_PCCR_UART4_REG CCM_PCCR0
188#define CCM_PCCR_UART3_OFFSET 2
189#define CCM_PCCR_UART3_REG CCM_PCCR0
190#define CCM_PCCR_UART2_OFFSET 1
191#define CCM_PCCR_UART2_REG CCM_PCCR0
192#define CCM_PCCR_UART1_OFFSET 0
193#define CCM_PCCR_UART1_REG CCM_PCCR0
194
195#define CCM_PCCR_OWIRE_OFFSET 31
196#define CCM_PCCR_OWIRE_REG CCM_PCCR1
197#define CCM_PCCR_KPP_OFFSET 30
198#define CCM_PCCR_KPP_REG CCM_PCCR1
199#define CCM_PCCR_RTC_OFFSET 29
200#define CCM_PCCR_RTC_REG CCM_PCCR1
201#define CCM_PCCR_PWM_OFFSET 28
202#define CCM_PCCR_PWM_REG CCM_PCCR1
203#define CCM_PCCR_GPT3_OFFSET 27
204#define CCM_PCCR_GPT3_REG CCM_PCCR1
205#define CCM_PCCR_GPT2_OFFSET 26
206#define CCM_PCCR_GPT2_REG CCM_PCCR1
207#define CCM_PCCR_GPT1_OFFSET 25
208#define CCM_PCCR_GPT1_REG CCM_PCCR1
209#define CCM_PCCR_WDT_OFFSET 24
210#define CCM_PCCR_WDT_REG CCM_PCCR1
211#define CCM_PCCR_CSPI3_OFFSET 23
212#define CCM_PCCR_CSPI3_REG CCM_PCCR1
213
214#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET)
215#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET)
216#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET)
217#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET)
218#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET)
219#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET)
220#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET)
221#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET)
222#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET)
223#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET)
224#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET)
225#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET)
226#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET)
227#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET)
228#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
229#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
230#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET)
231#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET)
232#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET)
233#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET)
234#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET)
235#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET)
236#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET)
237#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET)
238#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET)
239#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET)
240#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET)
241#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET)
242#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET)
243#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET)
244#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET)
245#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET)
246#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET)
247#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET)
248#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET)
249#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET)
250#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET)
251
252#define CCM_CCSR_32KSR (1 << 15)
253
254#define CCM_CCSR_CLKMODE1 (1 << 9)
255#define CCM_CCSR_CLKMODE0 (1 << 8)
256
257#define CCM_CCSR_CLKOSEL_OFFSET 0
258#define CCM_CCSR_CLKOSEL_MASK 0x1f
259
260#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */
261#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
262
263static int _clk_enable(struct clk *clk)
264{
265 u32 reg;
266
267 reg = __raw_readl(clk->enable_reg);
268 reg |= 1 << clk->enable_shift;
269 __raw_writel(reg, clk->enable_reg);
270 return 0;
271}
272
273static void _clk_disable(struct clk *clk)
274{
275 u32 reg;
276
277 reg = __raw_readl(clk->enable_reg);
278 reg &= ~(1 << clk->enable_shift);
279 __raw_writel(reg, clk->enable_reg);
280}
281
282static unsigned long _clk_generic_round_rate(struct clk *clk,
283 unsigned long rate,
284 u32 max_divisor)
285{
286 u32 div;
287 unsigned long parent_rate;
288
289 parent_rate = clk_get_rate(clk->parent);
290
291 div = parent_rate / rate;
292 if (parent_rate % rate)
293 div++;
294
295 if (div > max_divisor)
296 div = max_divisor;
297
298 return parent_rate / div;
299}
300
301static int _clk_spll_enable(struct clk *clk)
302{
303 u32 reg;
304
305 reg = __raw_readl(CCM_CSCR);
306 reg |= CCM_CSCR_SPEN;
307 __raw_writel(reg, CCM_CSCR);
308
309 while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
310 ;
311 return 0;
312}
313
314static void _clk_spll_disable(struct clk *clk)
315{
316 u32 reg;
317
318 reg = __raw_readl(CCM_CSCR);
319 reg &= ~CCM_CSCR_SPEN;
320 __raw_writel(reg, CCM_CSCR);
321}
322
323
324#define CSCR() (__raw_readl(CCM_CSCR))
325#define PCDR0() (__raw_readl(CCM_PCDR0))
326#define PCDR1() (__raw_readl(CCM_PCDR1))
327
328static unsigned long _clk_perclkx_round_rate(struct clk *clk,
329 unsigned long rate)
330{
331 return _clk_generic_round_rate(clk, rate, 64);
332}
333
334static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
335{
336 u32 reg;
337 u32 div;
338 unsigned long parent_rate;
339
340 parent_rate = clk_get_rate(clk->parent);
341
342 if (clk->id < 0 || clk->id > 3)
343 return -EINVAL;
344
345 div = parent_rate / rate;
346 if (div > 64 || div < 1 || ((parent_rate / div) != rate))
347 return -EINVAL;
348 div--;
349
350 reg =
351 __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
352 (clk->id << 3));
353 reg |= div << (clk->id << 3);
354 __raw_writel(reg, CCM_PCDR1);
355
356 return 0;
357}
358
359static unsigned long _clk_usb_recalc(struct clk *clk)
360{
361 unsigned long usb_pdf;
362 unsigned long parent_rate;
363
364 parent_rate = clk_get_rate(clk->parent);
365
366 usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
367
368 return parent_rate / (usb_pdf + 1U);
369}
370
371static unsigned long _clk_usb_round_rate(struct clk *clk,
372 unsigned long rate)
373{
374 return _clk_generic_round_rate(clk, rate, 8);
375}
376
377static int _clk_usb_set_rate(struct clk *clk, unsigned long rate)
378{
379 u32 reg;
380 u32 div;
381 unsigned long parent_rate;
382
383 parent_rate = clk_get_rate(clk->parent);
384
385 div = parent_rate / rate;
386 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
387 return -EINVAL;
388 div--;
389
390 reg = CSCR() & ~CCM_CSCR_USB_MASK;
391 reg |= div << CCM_CSCR_USB_OFFSET;
392 __raw_writel(reg, CCM_CSCR);
393
394 return 0;
395}
396
397static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
398{
399 unsigned long parent_rate;
400
401 parent_rate = clk_get_rate(clk->parent);
402
403 pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
404
405 return 2UL * parent_rate / pdf;
406}
407
408static unsigned long _clk_ssi1_recalc(struct clk *clk)
409{
410 return _clk_ssix_recalc(clk,
411 (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK)
412 >> CCM_PCDR0_SSI1BAUDDIV_OFFSET);
413}
414
415static unsigned long _clk_ssi2_recalc(struct clk *clk)
416{
417 return _clk_ssix_recalc(clk,
418 (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
419 CCM_PCDR0_SSI2BAUDDIV_OFFSET);
420}
421
422static unsigned long _clk_nfc_recalc(struct clk *clk)
423{
424 unsigned long nfc_pdf;
425 unsigned long parent_rate;
426
427 parent_rate = clk_get_rate(clk->parent);
428
429 nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK)
430 >> CCM_PCDR0_NFCDIV_OFFSET;
431
432 return parent_rate / (nfc_pdf + 1);
433}
434
435static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
436{
437 return clk->parent->round_rate(clk->parent, rate);
438}
439
440static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
441{
442 return clk->parent->set_rate(clk->parent, rate);
443}
444
445static unsigned long external_high_reference; /* in Hz */
446
447static unsigned long get_high_reference_clock_rate(struct clk *clk)
448{
449 return external_high_reference;
450}
451
452/*
453 * the high frequency external clock reference
454 * Default case is 26MHz.
455 */
456static struct clk ckih_clk = {
457 .get_rate = get_high_reference_clock_rate,
458};
459
460static unsigned long external_low_reference; /* in Hz */
461
462static unsigned long get_low_reference_clock_rate(struct clk *clk)
463{
464 return external_low_reference;
465}
466
467/*
468 * the low frequency external clock reference
469 * Default case is 32.768kHz.
470 */
471static struct clk ckil_clk = {
472 .get_rate = get_low_reference_clock_rate,
473};
474
475
476static unsigned long _clk_fpm_recalc(struct clk *clk)
477{
478 return clk_get_rate(clk->parent) * 512;
479}
480
481/* Output of frequency pre multiplier */
482static struct clk fpm_clk = {
483 .parent = &ckil_clk,
484 .get_rate = _clk_fpm_recalc,
485};
486
487static unsigned long get_mpll_clk(struct clk *clk)
488{
489 uint32_t reg;
490 unsigned long ref_clk;
491 unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
492 unsigned long long temp;
493
494 ref_clk = clk_get_rate(clk->parent);
495
496 reg = __raw_readl(CCM_MPCTL0);
497 pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
498 mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
499 mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
500 mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
501
502 mfi = (mfi <= 5) ? 5 : mfi;
503 temp = 2LL * ref_clk * mfn;
504 do_div(temp, mfd + 1);
505 temp = 2LL * ref_clk * mfi + temp;
506 do_div(temp, pdf + 1);
507
508 return (unsigned long)temp;
509}
510
511static struct clk mpll_clk = {
512 .parent = &ckih_clk,
513 .get_rate = get_mpll_clk,
514};
515
516static unsigned long _clk_fclk_get_rate(struct clk *clk)
517{
518 unsigned long parent_rate;
519 u32 div;
520
521 div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
522 parent_rate = clk_get_rate(clk->parent);
523
524 return parent_rate / (div+1);
525}
526
527static struct clk fclk_clk = {
528 .parent = &mpll_clk,
529 .get_rate = _clk_fclk_get_rate
530};
531
532static unsigned long get_spll_clk(struct clk *clk)
533{
534 uint32_t reg;
535 unsigned long ref_clk;
536 unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
537 unsigned long long temp;
538
539 ref_clk = clk_get_rate(clk->parent);
540
541 reg = __raw_readl(CCM_SPCTL0);
542 pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
543 mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
544 mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
545 mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
546
547 mfi = (mfi <= 5) ? 5 : mfi;
548 temp = 2LL * ref_clk * mfn;
549 do_div(temp, mfd + 1);
550 temp = 2LL * ref_clk * mfi + temp;
551 do_div(temp, pdf + 1);
552
553 return (unsigned long)temp;
554}
555
556static struct clk spll_clk = {
557 .parent = &ckih_clk,
558 .get_rate = get_spll_clk,
559 .enable = _clk_spll_enable,
560 .disable = _clk_spll_disable,
561};
562
563static unsigned long get_hclk_clk(struct clk *clk)
564{
565 unsigned long rate;
566 unsigned long bclk_pdf;
567
568 bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
569 >> CCM_CSCR_BCLK_OFFSET;
570
571 rate = clk_get_rate(clk->parent);
572 return rate / (bclk_pdf + 1);
573}
574
575static struct clk hclk_clk = {
576 .parent = &fclk_clk,
577 .get_rate = get_hclk_clk,
578};
579
580static unsigned long get_ipg_clk(struct clk *clk)
581{
582 unsigned long rate;
583 unsigned long ipg_pdf;
584
585 ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
586
587 rate = clk_get_rate(clk->parent);
588 return rate / (ipg_pdf + 1);
589}
590
591static struct clk ipg_clk = {
592 .parent = &hclk_clk,
593 .get_rate = get_ipg_clk,
594};
595
596static unsigned long _clk_perclkx_recalc(struct clk *clk)
597{
598 unsigned long perclk_pdf;
599 unsigned long parent_rate;
600
601 parent_rate = clk_get_rate(clk->parent);
602
603 if (clk->id < 0 || clk->id > 3)
604 return 0;
605
606 perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
607
608 return parent_rate / (perclk_pdf + 1);
609}
610
611static struct clk per_clk[] = {
612 {
613 .id = 0,
614 .parent = &mpll_clk,
615 .get_rate = _clk_perclkx_recalc,
616 }, {
617 .id = 1,
618 .parent = &mpll_clk,
619 .get_rate = _clk_perclkx_recalc,
620 }, {
621 .id = 2,
622 .parent = &mpll_clk,
623 .round_rate = _clk_perclkx_round_rate,
624 .set_rate = _clk_perclkx_set_rate,
625 .get_rate = _clk_perclkx_recalc,
626 /* Enable/Disable done via lcd_clkc[1] */
627 }, {
628 .id = 3,
629 .parent = &mpll_clk,
630 .round_rate = _clk_perclkx_round_rate,
631 .set_rate = _clk_perclkx_set_rate,
632 .get_rate = _clk_perclkx_recalc,
633 /* Enable/Disable done via csi_clk[1] */
634 },
635};
636
637static struct clk uart_ipg_clk[];
638
639static struct clk uart_clk[] = {
640 {
641 .id = 0,
642 .parent = &per_clk[0],
643 .secondary = &uart_ipg_clk[0],
644 }, {
645 .id = 1,
646 .parent = &per_clk[0],
647 .secondary = &uart_ipg_clk[1],
648 }, {
649 .id = 2,
650 .parent = &per_clk[0],
651 .secondary = &uart_ipg_clk[2],
652 }, {
653 .id = 3,
654 .parent = &per_clk[0],
655 .secondary = &uart_ipg_clk[3],
656 },
657};
658
659static struct clk uart_ipg_clk[] = {
660 {
661 .id = 0,
662 .parent = &ipg_clk,
663 .enable = _clk_enable,
664 .enable_reg = CCM_PCCR_UART1_REG,
665 .enable_shift = CCM_PCCR_UART1_OFFSET,
666 .disable = _clk_disable,
667 }, {
668 .id = 1,
669 .parent = &ipg_clk,
670 .enable = _clk_enable,
671 .enable_reg = CCM_PCCR_UART2_REG,
672 .enable_shift = CCM_PCCR_UART2_OFFSET,
673 .disable = _clk_disable,
674 }, {
675 .id = 2,
676 .parent = &ipg_clk,
677 .enable = _clk_enable,
678 .enable_reg = CCM_PCCR_UART3_REG,
679 .enable_shift = CCM_PCCR_UART3_OFFSET,
680 .disable = _clk_disable,
681 }, {
682 .id = 3,
683 .parent = &ipg_clk,
684 .enable = _clk_enable,
685 .enable_reg = CCM_PCCR_UART4_REG,
686 .enable_shift = CCM_PCCR_UART4_OFFSET,
687 .disable = _clk_disable,
688 },
689};
690
691static struct clk gpt_ipg_clk[];
692
693static struct clk gpt_clk[] = {
694 {
695 .id = 0,
696 .parent = &per_clk[0],
697 .secondary = &gpt_ipg_clk[0],
698 }, {
699 .id = 1,
700 .parent = &per_clk[0],
701 .secondary = &gpt_ipg_clk[1],
702 }, {
703 .id = 2,
704 .parent = &per_clk[0],
705 .secondary = &gpt_ipg_clk[2],
706 },
707};
708
709static struct clk gpt_ipg_clk[] = {
710 {
711 .id = 0,
712 .parent = &ipg_clk,
713 .enable = _clk_enable,
714 .enable_reg = CCM_PCCR_GPT1_REG,
715 .enable_shift = CCM_PCCR_GPT1_OFFSET,
716 .disable = _clk_disable,
717 }, {
718 .id = 1,
719 .parent = &ipg_clk,
720 .enable = _clk_enable,
721 .enable_reg = CCM_PCCR_GPT2_REG,
722 .enable_shift = CCM_PCCR_GPT2_OFFSET,
723 .disable = _clk_disable,
724 }, {
725 .id = 2,
726 .parent = &ipg_clk,
727 .enable = _clk_enable,
728 .enable_reg = CCM_PCCR_GPT3_REG,
729 .enable_shift = CCM_PCCR_GPT3_OFFSET,
730 .disable = _clk_disable,
731 },
732};
733
734static struct clk pwm_clk[] = {
735 {
736 .parent = &per_clk[0],
737 .secondary = &pwm_clk[1],
738 }, {
739 .parent = &ipg_clk,
740 .enable = _clk_enable,
741 .enable_reg = CCM_PCCR_PWM_REG,
742 .enable_shift = CCM_PCCR_PWM_OFFSET,
743 .disable = _clk_disable,
744 },
745};
746
747static struct clk sdhc_ipg_clk[];
748
749static struct clk sdhc_clk[] = {
750 {
751 .id = 0,
752 .parent = &per_clk[1],
753 .secondary = &sdhc_ipg_clk[0],
754 }, {
755 .id = 1,
756 .parent = &per_clk[1],
757 .secondary = &sdhc_ipg_clk[1],
758 },
759};
760
761static struct clk sdhc_ipg_clk[] = {
762 {
763 .id = 0,
764 .parent = &ipg_clk,
765 .enable = _clk_enable,
766 .enable_reg = CCM_PCCR_SDHC1_REG,
767 .enable_shift = CCM_PCCR_SDHC1_OFFSET,
768 .disable = _clk_disable,
769 }, {
770 .id = 1,
771 .parent = &ipg_clk,
772 .enable = _clk_enable,
773 .enable_reg = CCM_PCCR_SDHC2_REG,
774 .enable_shift = CCM_PCCR_SDHC2_OFFSET,
775 .disable = _clk_disable,
776 },
777};
778
779static struct clk cspi_ipg_clk[];
780
781static struct clk cspi_clk[] = {
782 {
783 .id = 0,
784 .parent = &per_clk[1],
785 .secondary = &cspi_ipg_clk[0],
786 }, {
787 .id = 1,
788 .parent = &per_clk[1],
789 .secondary = &cspi_ipg_clk[1],
790 }, {
791 .id = 2,
792 .parent = &per_clk[1],
793 .secondary = &cspi_ipg_clk[2],
794 },
795};
796
797static struct clk cspi_ipg_clk[] = {
798 {
799 .id = 0,
800 .parent = &ipg_clk,
801 .enable = _clk_enable,
802 .enable_reg = CCM_PCCR_CSPI1_REG,
803 .enable_shift = CCM_PCCR_CSPI1_OFFSET,
804 .disable = _clk_disable,
805 }, {
806 .id = 1,
807 .parent = &ipg_clk,
808 .enable = _clk_enable,
809 .enable_reg = CCM_PCCR_CSPI2_REG,
810 .enable_shift = CCM_PCCR_CSPI2_OFFSET,
811 .disable = _clk_disable,
812 }, {
813 .id = 3,
814 .parent = &ipg_clk,
815 .enable = _clk_enable,
816 .enable_reg = CCM_PCCR_CSPI3_REG,
817 .enable_shift = CCM_PCCR_CSPI3_OFFSET,
818 .disable = _clk_disable,
819 },
820};
821
822static struct clk lcdc_clk[] = {
823 {
824 .parent = &per_clk[2],
825 .secondary = &lcdc_clk[1],
826 .round_rate = _clk_parent_round_rate,
827 .set_rate = _clk_parent_set_rate,
828 }, {
829 .parent = &ipg_clk,
830 .secondary = &lcdc_clk[2],
831 .enable = _clk_enable,
832 .enable_reg = CCM_PCCR_LCDC_REG,
833 .enable_shift = CCM_PCCR_LCDC_OFFSET,
834 .disable = _clk_disable,
835 }, {
836 .parent = &hclk_clk,
837 .enable = _clk_enable,
838 .enable_reg = CCM_PCCR_HCLK_LCDC_REG,
839 .enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET,
840 .disable = _clk_disable,
841 },
842};
843
844static struct clk csi_clk[] = {
845 {
846 .parent = &per_clk[3],
847 .secondary = &csi_clk[1],
848 .round_rate = _clk_parent_round_rate,
849 .set_rate = _clk_parent_set_rate,
850 }, {
851 .parent = &hclk_clk,
852 .enable = _clk_enable,
853 .enable_reg = CCM_PCCR_HCLK_CSI_REG,
854 .enable_shift = CCM_PCCR_HCLK_CSI_OFFSET,
855 .disable = _clk_disable,
856 },
857};
858
859static struct clk usb_clk[] = {
860 {
861 .parent = &spll_clk,
862 .secondary = &usb_clk[1],
863 .get_rate = _clk_usb_recalc,
864 .enable = _clk_enable,
865 .enable_reg = CCM_PCCR_USBOTG_REG,
866 .enable_shift = CCM_PCCR_USBOTG_OFFSET,
867 .disable = _clk_disable,
868 .round_rate = _clk_usb_round_rate,
869 .set_rate = _clk_usb_set_rate,
870 }, {
871 .parent = &hclk_clk,
872 .enable = _clk_enable,
873 .enable_reg = CCM_PCCR_HCLK_USBOTG_REG,
874 .enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET,
875 .disable = _clk_disable,
876 }
877};
878
879static struct clk ssi_ipg_clk[];
880
881static struct clk ssi_clk[] = {
882 {
883 .id = 0,
884 .parent = &mpll_clk,
885 .secondary = &ssi_ipg_clk[0],
886 .get_rate = _clk_ssi1_recalc,
887 .enable = _clk_enable,
888 .enable_reg = CCM_PCCR_SSI1_BAUD_REG,
889 .enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET,
890 .disable = _clk_disable,
891 }, {
892 .id = 1,
893 .parent = &mpll_clk,
894 .secondary = &ssi_ipg_clk[1],
895 .get_rate = _clk_ssi2_recalc,
896 .enable = _clk_enable,
897 .enable_reg = CCM_PCCR_SSI2_BAUD_REG,
898 .enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET,
899 .disable = _clk_disable,
900 },
901};
902
903static struct clk ssi_ipg_clk[] = {
904 {
905 .id = 0,
906 .parent = &ipg_clk,
907 .enable = _clk_enable,
908 .enable_reg = CCM_PCCR_SSI1_REG,
909 .enable_shift = CCM_PCCR_SSI1_IPG_OFFSET,
910 .disable = _clk_disable,
911 }, {
912 .id = 1,
913 .parent = &ipg_clk,
914 .enable = _clk_enable,
915 .enable_reg = CCM_PCCR_SSI2_REG,
916 .enable_shift = CCM_PCCR_SSI2_IPG_OFFSET,
917 .disable = _clk_disable,
918 },
919};
920
921
922static struct clk nfc_clk = {
923 .parent = &fclk_clk,
924 .get_rate = _clk_nfc_recalc,
925 .enable = _clk_enable,
926 .enable_reg = CCM_PCCR_NFC_REG,
927 .enable_shift = CCM_PCCR_NFC_OFFSET,
928 .disable = _clk_disable,
929};
930
931static struct clk dma_clk[] = {
932 {
933 .parent = &hclk_clk,
934 .enable = _clk_enable,
935 .enable_reg = CCM_PCCR_DMA_REG,
936 .enable_shift = CCM_PCCR_DMA_OFFSET,
937 .disable = _clk_disable,
938 .secondary = &dma_clk[1],
939 }, {
940 .enable = _clk_enable,
941 .enable_reg = CCM_PCCR_HCLK_DMA_REG,
942 .enable_shift = CCM_PCCR_HCLK_DMA_OFFSET,
943 .disable = _clk_disable,
944 },
945};
946
947static struct clk brom_clk = {
948 .parent = &hclk_clk,
949 .enable = _clk_enable,
950 .enable_reg = CCM_PCCR_HCLK_BROM_REG,
951 .enable_shift = CCM_PCCR_HCLK_BROM_OFFSET,
952 .disable = _clk_disable,
953};
954
955static struct clk emma_clk[] = {
956 {
957 .parent = &hclk_clk,
958 .enable = _clk_enable,
959 .enable_reg = CCM_PCCR_EMMA_REG,
960 .enable_shift = CCM_PCCR_EMMA_OFFSET,
961 .disable = _clk_disable,
962 .secondary = &emma_clk[1],
963 }, {
964 .enable = _clk_enable,
965 .enable_reg = CCM_PCCR_HCLK_EMMA_REG,
966 .enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET,
967 .disable = _clk_disable,
968 }
969};
970
971static struct clk slcdc_clk[] = {
972 {
973 .parent = &hclk_clk,
974 .enable = _clk_enable,
975 .enable_reg = CCM_PCCR_SLCDC_REG,
976 .enable_shift = CCM_PCCR_SLCDC_OFFSET,
977 .disable = _clk_disable,
978 .secondary = &slcdc_clk[1],
979 }, {
980 .enable = _clk_enable,
981 .enable_reg = CCM_PCCR_HCLK_SLCDC_REG,
982 .enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET,
983 .disable = _clk_disable,
984 }
985};
986
987static struct clk wdog_clk = {
988 .parent = &ipg_clk,
989 .enable = _clk_enable,
990 .enable_reg = CCM_PCCR_WDT_REG,
991 .enable_shift = CCM_PCCR_WDT_OFFSET,
992 .disable = _clk_disable,
993};
994
995static struct clk gpio_clk = {
996 .parent = &ipg_clk,
997 .enable = _clk_enable,
998 .enable_reg = CCM_PCCR_GPIO_REG,
999 .enable_shift = CCM_PCCR_GPIO_OFFSET,
1000 .disable = _clk_disable,
1001};
1002
1003static struct clk i2c_clk = {
1004 .id = 0,
1005 .parent = &ipg_clk,
1006 .enable = _clk_enable,
1007 .enable_reg = CCM_PCCR_I2C1_REG,
1008 .enable_shift = CCM_PCCR_I2C1_OFFSET,
1009 .disable = _clk_disable,
1010};
1011
1012static struct clk kpp_clk = {
1013 .parent = &ipg_clk,
1014 .enable = _clk_enable,
1015 .enable_reg = CCM_PCCR_KPP_REG,
1016 .enable_shift = CCM_PCCR_KPP_OFFSET,
1017 .disable = _clk_disable,
1018};
1019
1020static struct clk owire_clk = {
1021 .parent = &ipg_clk,
1022 .enable = _clk_enable,
1023 .enable_reg = CCM_PCCR_OWIRE_REG,
1024 .enable_shift = CCM_PCCR_OWIRE_OFFSET,
1025 .disable = _clk_disable,
1026};
1027
1028static struct clk rtc_clk = {
1029 .parent = &ipg_clk,
1030 .enable = _clk_enable,
1031 .enable_reg = CCM_PCCR_RTC_REG,
1032 .enable_shift = CCM_PCCR_RTC_OFFSET,
1033 .disable = _clk_disable,
1034};
1035
1036static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
1037{
1038 return _clk_generic_round_rate(clk, rate, 8);
1039}
1040
1041static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
1042{
1043 u32 reg;
1044 u32 div;
1045 unsigned long parent_rate;
1046
1047 parent_rate = clk_get_rate(clk->parent);
1048
1049 div = parent_rate / rate;
1050
1051 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
1052 return -EINVAL;
1053 div--;
1054
1055 reg = __raw_readl(CCM_PCDR0);
1056
1057 if (clk->parent == &usb_clk[0]) {
1058 reg &= ~CCM_PCDR0_48MDIV_MASK;
1059 reg |= div << CCM_PCDR0_48MDIV_OFFSET;
1060 }
1061 __raw_writel(reg, CCM_PCDR0);
1062
1063 return 0;
1064}
1065
1066static unsigned long _clk_clko_recalc(struct clk *clk)
1067{
1068 u32 div = 0;
1069 unsigned long parent_rate;
1070
1071 parent_rate = clk_get_rate(clk->parent);
1072
1073 if (clk->parent == &usb_clk[0]) /* 48M */
1074 div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK
1075 >> CCM_PCDR0_48MDIV_OFFSET;
1076 div++;
1077
1078 return parent_rate / div;
1079}
1080
1081static struct clk clko_clk;
1082
1083static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
1084{
1085 u32 reg;
1086
1087 reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
1088
1089 if (parent == &ckil_clk)
1090 reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
1091 else if (parent == &fpm_clk)
1092 reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET;
1093 else if (parent == &ckih_clk)
1094 reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
1095 else if (parent == mpll_clk.parent)
1096 reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
1097 else if (parent == spll_clk.parent)
1098 reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
1099 else if (parent == &mpll_clk)
1100 reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
1101 else if (parent == &spll_clk)
1102 reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
1103 else if (parent == &fclk_clk)
1104 reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
1105 else if (parent == &hclk_clk)
1106 reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
1107 else if (parent == &ipg_clk)
1108 reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
1109 else if (parent == &per_clk[0])
1110 reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
1111 else if (parent == &per_clk[1])
1112 reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
1113 else if (parent == &per_clk[2])
1114 reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
1115 else if (parent == &per_clk[3])
1116 reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
1117 else if (parent == &ssi_clk[0])
1118 reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
1119 else if (parent == &ssi_clk[1])
1120 reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
1121 else if (parent == &nfc_clk)
1122 reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
1123 else if (parent == &usb_clk[0])
1124 reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET;
1125 else if (parent == &clko_clk)
1126 reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
1127 else
1128 return -EINVAL;
1129
1130 __raw_writel(reg, CCM_CCSR);
1131
1132 return 0;
1133}
1134
1135static struct clk clko_clk = {
1136 .get_rate = _clk_clko_recalc,
1137 .set_rate = _clk_clko_set_rate,
1138 .round_rate = _clk_clko_round_rate,
1139 .set_parent = _clk_clko_set_parent,
1140};
1141
1142
1143#define _REGISTER_CLOCK(d, n, c) \
1144 { \
1145 .dev_id = d, \
1146 .con_id = n, \
1147 .clk = &c, \
1148 },
1149static struct clk_lookup lookups[] = {
1150/* It's unlikely that any driver wants one of them directly:
1151 _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
1152 _REGISTER_CLOCK(NULL, "ckil", ckil_clk)
1153 _REGISTER_CLOCK(NULL, "fpm", fpm_clk)
1154 _REGISTER_CLOCK(NULL, "mpll", mpll_clk)
1155 _REGISTER_CLOCK(NULL, "spll", spll_clk)
1156 _REGISTER_CLOCK(NULL, "fclk", fclk_clk)
1157 _REGISTER_CLOCK(NULL, "hclk", hclk_clk)
1158 _REGISTER_CLOCK(NULL, "ipg", ipg_clk)
1159*/
1160 _REGISTER_CLOCK(NULL, "perclk1", per_clk[0])
1161 _REGISTER_CLOCK(NULL, "perclk2", per_clk[1])
1162 _REGISTER_CLOCK(NULL, "perclk3", per_clk[2])
1163 _REGISTER_CLOCK(NULL, "perclk4", per_clk[3])
1164 _REGISTER_CLOCK(NULL, "clko", clko_clk)
1165 _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0])
1166 _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1])
1167 _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2])
1168 _REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[3])
1169 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0])
1170 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1])
1171 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2])
1172 _REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
1173 _REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
1174 _REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
1175 _REGISTER_CLOCK(NULL, "cspi1", cspi_clk[0])
1176 _REGISTER_CLOCK(NULL, "cspi2", cspi_clk[1])
1177 _REGISTER_CLOCK(NULL, "cspi3", cspi_clk[2])
1178 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0])
1179 _REGISTER_CLOCK(NULL, "csi", csi_clk[0])
1180 _REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0])
1181 _REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
1182 _REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
1183 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
1184 _REGISTER_CLOCK(NULL, "dma", dma_clk[0])
1185 _REGISTER_CLOCK(NULL, "brom", brom_clk)
1186 _REGISTER_CLOCK(NULL, "emma", emma_clk[0])
1187 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
1188 _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
1189 _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
1190 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
1191 _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
1192 _REGISTER_CLOCK(NULL, "owire", owire_clk)
1193 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
1194};
1195
1196/*
1197 * must be called very early to get information about the
1198 * available clock rate when the timer framework starts
1199 */
1200int __init mx21_clocks_init(unsigned long lref, unsigned long href)
1201{
1202 u32 cscr;
1203
1204 external_low_reference = lref;
1205 external_high_reference = href;
1206
1207 /* detect clock reference for both system PLL */
1208 cscr = CSCR();
1209 if (cscr & CCM_CSCR_MCU)
1210 mpll_clk.parent = &ckih_clk;
1211 else
1212 mpll_clk.parent = &fpm_clk;
1213
1214 if (cscr & CCM_CSCR_SP)
1215 spll_clk.parent = &ckih_clk;
1216 else
1217 spll_clk.parent = &fpm_clk;
1218
1219 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
1220
1221 /* Turn off all clock gates */
1222 __raw_writel(0, CCM_PCCR0);
1223 __raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1);
1224
1225 /* This turns of the serial PLL as well */
1226 spll_clk.disable(&spll_clk);
1227
1228 /* This will propagate to all children and init all the clock rates. */
1229 clk_enable(&per_clk[0]);
1230 clk_enable(&gpio_clk);
1231
1232#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
1233 clk_enable(&uart_clk[0]);
1234#endif
1235
1236 mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
1237 MX21_INT_GPT1);
1238 return 0;
1239}
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
new file mode 100644
index 000000000000..5a1aa15c8a16
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx27.c
@@ -0,0 +1,763 @@
1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <linux/clk.h>
22#include <linux/io.h>
23#include <linux/module.h>
24
25#include <asm/clkdev.h>
26#include <asm/div64.h>
27
28#include <mach/clock.h>
29#include <mach/common.h>
30#include <mach/hardware.h>
31
32#define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
33
34/* Register offsets */
35#define CCM_CSCR IO_ADDR_CCM(0x0)
36#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
37#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
38#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
39#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
40#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
41#define CCM_PCDR0 IO_ADDR_CCM(0x18)
42#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
43#define CCM_PCCR0 IO_ADDR_CCM(0x20)
44#define CCM_PCCR1 IO_ADDR_CCM(0x24)
45#define CCM_CCSR IO_ADDR_CCM(0x28)
46#define CCM_PMCTL IO_ADDR_CCM(0x2c)
47#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
48#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
49
50#define CCM_CSCR_UPDATE_DIS (1 << 31)
51#define CCM_CSCR_SSI2 (1 << 23)
52#define CCM_CSCR_SSI1 (1 << 22)
53#define CCM_CSCR_VPU (1 << 21)
54#define CCM_CSCR_MSHC (1 << 20)
55#define CCM_CSCR_SPLLRES (1 << 19)
56#define CCM_CSCR_MPLLRES (1 << 18)
57#define CCM_CSCR_SP (1 << 17)
58#define CCM_CSCR_MCU (1 << 16)
59#define CCM_CSCR_OSC26MDIV (1 << 4)
60#define CCM_CSCR_OSC26M (1 << 3)
61#define CCM_CSCR_FPM (1 << 2)
62#define CCM_CSCR_SPEN (1 << 1)
63#define CCM_CSCR_MPEN (1 << 0)
64
65/* i.MX27 TO 2+ */
66#define CCM_CSCR_ARM_SRC (1 << 15)
67
68#define CCM_SPCTL1_LF (1 << 15)
69#define CCM_SPCTL1_BRMO (1 << 6)
70
71static struct clk mpll_main1_clk, mpll_main2_clk;
72
73static int clk_pccr_enable(struct clk *clk)
74{
75 unsigned long reg;
76
77 if (!clk->enable_reg)
78 return 0;
79
80 reg = __raw_readl(clk->enable_reg);
81 reg |= 1 << clk->enable_shift;
82 __raw_writel(reg, clk->enable_reg);
83
84 return 0;
85}
86
87static void clk_pccr_disable(struct clk *clk)
88{
89 unsigned long reg;
90
91 if (!clk->enable_reg)
92 return;
93
94 reg = __raw_readl(clk->enable_reg);
95 reg &= ~(1 << clk->enable_shift);
96 __raw_writel(reg, clk->enable_reg);
97}
98
99static int clk_spll_enable(struct clk *clk)
100{
101 unsigned long reg;
102
103 reg = __raw_readl(CCM_CSCR);
104 reg |= CCM_CSCR_SPEN;
105 __raw_writel(reg, CCM_CSCR);
106
107 while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF));
108
109 return 0;
110}
111
112static void clk_spll_disable(struct clk *clk)
113{
114 unsigned long reg;
115
116 reg = __raw_readl(CCM_CSCR);
117 reg &= ~CCM_CSCR_SPEN;
118 __raw_writel(reg, CCM_CSCR);
119}
120
121static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
122{
123 int cscr = __raw_readl(CCM_CSCR);
124
125 if (clk->parent == parent)
126 return 0;
127
128 if (mx27_revision() >= CHIP_REV_2_0) {
129 if (parent == &mpll_main1_clk) {
130 cscr |= CCM_CSCR_ARM_SRC;
131 } else {
132 if (parent == &mpll_main2_clk)
133 cscr &= ~CCM_CSCR_ARM_SRC;
134 else
135 return -EINVAL;
136 }
137 __raw_writel(cscr, CCM_CSCR);
138 clk->parent = parent;
139 return 0;
140 }
141 return -ENODEV;
142}
143
144static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate)
145{
146 int div;
147 unsigned long parent_rate;
148
149 parent_rate = clk_get_rate(clk->parent);
150
151 div = parent_rate / rate;
152 if (parent_rate % rate)
153 div++;
154
155 if (div > 4)
156 div = 4;
157
158 return parent_rate / div;
159}
160
161static int set_rate_cpu(struct clk *clk, unsigned long rate)
162{
163 unsigned int div;
164 uint32_t reg;
165 unsigned long parent_rate;
166
167 parent_rate = clk_get_rate(clk->parent);
168
169 div = parent_rate / rate;
170
171 if (div > 4 || div < 1 || ((parent_rate / div) != rate))
172 return -EINVAL;
173
174 div--;
175
176 reg = __raw_readl(CCM_CSCR);
177 if (mx27_revision() >= CHIP_REV_2_0) {
178 reg &= ~(3 << 12);
179 reg |= div << 12;
180 reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN);
181 __raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR);
182 } else {
183 printk(KERN_ERR "Can't set CPU frequency!\n");
184 }
185
186 return 0;
187}
188
189static unsigned long round_rate_per(struct clk *clk, unsigned long rate)
190{
191 u32 div;
192 unsigned long parent_rate;
193
194 parent_rate = clk_get_rate(clk->parent);
195
196 div = parent_rate / rate;
197 if (parent_rate % rate)
198 div++;
199
200 if (div > 64)
201 div = 64;
202
203 return parent_rate / div;
204}
205
206static int set_rate_per(struct clk *clk, unsigned long rate)
207{
208 u32 reg;
209 u32 div;
210 unsigned long parent_rate;
211
212 parent_rate = clk_get_rate(clk->parent);
213
214 if (clk->id < 0 || clk->id > 3)
215 return -EINVAL;
216
217 div = parent_rate / rate;
218 if (div > 64 || div < 1 || ((parent_rate / div) != rate))
219 return -EINVAL;
220 div--;
221
222 reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3));
223 reg |= div << (clk->id << 3);
224 __raw_writel(reg, CCM_PCDR1);
225
226 return 0;
227}
228
229static unsigned long get_rate_usb(struct clk *clk)
230{
231 unsigned long usb_pdf;
232 unsigned long parent_rate;
233
234 parent_rate = clk_get_rate(clk->parent);
235
236 usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7;
237
238 return parent_rate / (usb_pdf + 1U);
239}
240
241static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
242{
243 unsigned long parent_rate;
244
245 parent_rate = clk_get_rate(clk->parent);
246
247 if (mx27_revision() >= CHIP_REV_2_0)
248 pdf += 4; /* MX27 TO2+ */
249 else
250 pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
251
252 return 2UL * parent_rate / pdf;
253}
254
255static unsigned long get_rate_ssi1(struct clk *clk)
256{
257 return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f);
258}
259
260static unsigned long get_rate_ssi2(struct clk *clk)
261{
262 return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f);
263}
264
265static unsigned long get_rate_nfc(struct clk *clk)
266{
267 unsigned long nfc_pdf;
268 unsigned long parent_rate;
269
270 parent_rate = clk_get_rate(clk->parent);
271
272 if (mx27_revision() >= CHIP_REV_2_0)
273 nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf;
274 else
275 nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf;
276
277 return parent_rate / (nfc_pdf + 1);
278}
279
280static unsigned long get_rate_vpu(struct clk *clk)
281{
282 unsigned long vpu_pdf;
283 unsigned long parent_rate;
284
285 parent_rate = clk_get_rate(clk->parent);
286
287 if (mx27_revision() >= CHIP_REV_2_0) {
288 vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f;
289 vpu_pdf += 4;
290 } else {
291 vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf;
292 vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
293 }
294
295 return 2UL * parent_rate / vpu_pdf;
296}
297
298static unsigned long round_rate_parent(struct clk *clk, unsigned long rate)
299{
300 return clk->parent->round_rate(clk->parent, rate);
301}
302
303static unsigned long get_rate_parent(struct clk *clk)
304{
305 return clk_get_rate(clk->parent);
306}
307
308static int set_rate_parent(struct clk *clk, unsigned long rate)
309{
310 return clk->parent->set_rate(clk->parent, rate);
311}
312
313/* in Hz */
314static unsigned long external_high_reference = 26000000;
315
316static unsigned long get_rate_high_reference(struct clk *clk)
317{
318 return external_high_reference;
319}
320
321/* in Hz */
322static unsigned long external_low_reference = 32768;
323
324static unsigned long get_rate_low_reference(struct clk *clk)
325{
326 return external_low_reference;
327}
328
329static unsigned long get_rate_fpm(struct clk *clk)
330{
331 return clk_get_rate(clk->parent) * 1024;
332}
333
334static unsigned long get_rate_mpll(struct clk *clk)
335{
336 return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
337 clk_get_rate(clk->parent));
338}
339
340static unsigned long get_rate_mpll_main(struct clk *clk)
341{
342 unsigned long parent_rate;
343
344 parent_rate = clk_get_rate(clk->parent);
345
346 /* i.MX27 TO2:
347 * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2
348 * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3
349 */
350 if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1)
351 return 2UL * parent_rate / 3UL;
352
353 return parent_rate;
354}
355
356static unsigned long get_rate_spll(struct clk *clk)
357{
358 uint32_t reg;
359 unsigned long rate;
360
361 rate = clk_get_rate(clk->parent);
362
363 reg = __raw_readl(CCM_SPCTL0);
364
365 /* On TO2 we have to write the value back. Otherwise we
366 * read 0 from this register the next time.
367 */
368 if (mx27_revision() >= CHIP_REV_2_0)
369 __raw_writel(reg, CCM_SPCTL0);
370
371 return mxc_decode_pll(reg, rate);
372}
373
374static unsigned long get_rate_cpu(struct clk *clk)
375{
376 u32 div;
377 unsigned long rate;
378
379 if (mx27_revision() >= CHIP_REV_2_0)
380 div = (__raw_readl(CCM_CSCR) >> 12) & 0x3;
381 else
382 div = (__raw_readl(CCM_CSCR) >> 13) & 0x7;
383
384 rate = clk_get_rate(clk->parent);
385 return rate / (div + 1);
386}
387
388static unsigned long get_rate_ahb(struct clk *clk)
389{
390 unsigned long rate, bclk_pdf;
391
392 if (mx27_revision() >= CHIP_REV_2_0)
393 bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3;
394 else
395 bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf;
396
397 rate = clk_get_rate(clk->parent);
398 return rate / (bclk_pdf + 1);
399}
400
401static unsigned long get_rate_ipg(struct clk *clk)
402{
403 unsigned long rate, ipg_pdf;
404
405 if (mx27_revision() >= CHIP_REV_2_0)
406 return clk_get_rate(clk->parent);
407 else
408 ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1;
409
410 rate = clk_get_rate(clk->parent);
411 return rate / (ipg_pdf + 1);
412}
413
414static unsigned long get_rate_per(struct clk *clk)
415{
416 unsigned long perclk_pdf, parent_rate;
417
418 parent_rate = clk_get_rate(clk->parent);
419
420 if (clk->id < 0 || clk->id > 3)
421 return 0;
422
423 perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f;
424
425 return parent_rate / (perclk_pdf + 1);
426}
427
428/*
429 * the high frequency external clock reference
430 * Default case is 26MHz. Could be changed at runtime
431 * with a call to change_external_high_reference()
432 */
433static struct clk ckih_clk = {
434 .get_rate = get_rate_high_reference,
435};
436
437static struct clk mpll_clk = {
438 .parent = &ckih_clk,
439 .get_rate = get_rate_mpll,
440};
441
442/* For i.MX27 TO2, it is the MPLL path 1 of ARM core
443 * It provides the clock source whose rate is same as MPLL
444 */
445static struct clk mpll_main1_clk = {
446 .id = 0,
447 .parent = &mpll_clk,
448 .get_rate = get_rate_mpll_main,
449};
450
451/* For i.MX27 TO2, it is the MPLL path 2 of ARM core
452 * It provides the clock source whose rate is same MPLL * 2 / 3
453 */
454static struct clk mpll_main2_clk = {
455 .id = 1,
456 .parent = &mpll_clk,
457 .get_rate = get_rate_mpll_main,
458};
459
460static struct clk ahb_clk = {
461 .parent = &mpll_main2_clk,
462 .get_rate = get_rate_ahb,
463};
464
465static struct clk ipg_clk = {
466 .parent = &ahb_clk,
467 .get_rate = get_rate_ipg,
468};
469
470static struct clk cpu_clk = {
471 .parent = &mpll_main2_clk,
472 .set_parent = clk_cpu_set_parent,
473 .round_rate = round_rate_cpu,
474 .get_rate = get_rate_cpu,
475 .set_rate = set_rate_cpu,
476};
477
478static struct clk spll_clk = {
479 .parent = &ckih_clk,
480 .get_rate = get_rate_spll,
481 .enable = clk_spll_enable,
482 .disable = clk_spll_disable,
483};
484
485/*
486 * the low frequency external clock reference
487 * Default case is 32.768kHz.
488 */
489static struct clk ckil_clk = {
490 .get_rate = get_rate_low_reference,
491};
492
493/* Output of frequency pre multiplier */
494static struct clk fpm_clk = {
495 .parent = &ckil_clk,
496 .get_rate = get_rate_fpm,
497};
498
499#define PCCR0 CCM_PCCR0
500#define PCCR1 CCM_PCCR1
501
502#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
503 static struct clk name = { \
504 .id = i, \
505 .enable_reg = er, \
506 .enable_shift = es, \
507 .get_rate = gr, \
508 .enable = clk_pccr_enable, \
509 .disable = clk_pccr_disable, \
510 .secondary = s, \
511 .parent = p, \
512 }
513
514#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
515 static struct clk name = { \
516 .id = i, \
517 .enable_reg = er, \
518 .enable_shift = es, \
519 .get_rate = get_rate_##getsetround, \
520 .set_rate = set_rate_##getsetround, \
521 .round_rate = round_rate_##getsetround, \
522 .enable = clk_pccr_enable, \
523 .disable = clk_pccr_disable, \
524 .secondary = s, \
525 .parent = p, \
526 }
527
528/* Forward declaration to keep the following list in order */
529static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1,
530 dma_clk1, lcdc_clk2, vpu_clk1;
531
532/* All clocks we can gate through PCCRx in the order of PCCRx bits */
533DEFINE_CLOCK(ssi2_clk1, 1, PCCR0, 0, NULL, NULL, &ipg_clk);
534DEFINE_CLOCK(ssi1_clk1, 0, PCCR0, 1, NULL, NULL, &ipg_clk);
535DEFINE_CLOCK(slcdc_clk, 0, PCCR0, 2, NULL, &slcdc_clk1, &ahb_clk);
536DEFINE_CLOCK(sdhc3_clk1, 0, PCCR0, 3, NULL, NULL, &ipg_clk);
537DEFINE_CLOCK(sdhc2_clk1, 0, PCCR0, 4, NULL, NULL, &ipg_clk);
538DEFINE_CLOCK(sdhc1_clk1, 0, PCCR0, 5, NULL, NULL, &ipg_clk);
539DEFINE_CLOCK(scc_clk, 0, PCCR0, 6, NULL, NULL, &ipg_clk);
540DEFINE_CLOCK(sahara2_clk, 0, PCCR0, 7, NULL, &sahara2_clk1, &ahb_clk);
541DEFINE_CLOCK(rtic_clk, 0, PCCR0, 8, NULL, &rtic_clk1, &ahb_clk);
542DEFINE_CLOCK(rtc_clk, 0, PCCR0, 9, NULL, NULL, &ipg_clk);
543DEFINE_CLOCK(pwm_clk1, 0, PCCR0, 11, NULL, NULL, &ipg_clk);
544DEFINE_CLOCK(owire_clk, 0, PCCR0, 12, NULL, NULL, &ipg_clk);
545DEFINE_CLOCK(mstick_clk1, 0, PCCR0, 13, NULL, NULL, &ipg_clk);
546DEFINE_CLOCK(lcdc_clk1, 0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk);
547DEFINE_CLOCK(kpp_clk, 0, PCCR0, 15, NULL, NULL, &ipg_clk);
548DEFINE_CLOCK(iim_clk, 0, PCCR0, 16, NULL, NULL, &ipg_clk);
549DEFINE_CLOCK(i2c2_clk, 1, PCCR0, 17, NULL, NULL, &ipg_clk);
550DEFINE_CLOCK(i2c1_clk, 0, PCCR0, 18, NULL, NULL, &ipg_clk);
551DEFINE_CLOCK(gpt6_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
552DEFINE_CLOCK(gpt5_clk1, 0, PCCR0, 20, NULL, NULL, &ipg_clk);
553DEFINE_CLOCK(gpt4_clk1, 0, PCCR0, 21, NULL, NULL, &ipg_clk);
554DEFINE_CLOCK(gpt3_clk1, 0, PCCR0, 22, NULL, NULL, &ipg_clk);
555DEFINE_CLOCK(gpt2_clk1, 0, PCCR0, 23, NULL, NULL, &ipg_clk);
556DEFINE_CLOCK(gpt1_clk1, 0, PCCR0, 24, NULL, NULL, &ipg_clk);
557DEFINE_CLOCK(gpio_clk, 0, PCCR0, 25, NULL, NULL, &ipg_clk);
558DEFINE_CLOCK(fec_clk, 0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk);
559DEFINE_CLOCK(emma_clk, 0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk);
560DEFINE_CLOCK(dma_clk, 0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk);
561DEFINE_CLOCK(cspi13_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
562DEFINE_CLOCK(cspi2_clk1, 0, PCCR0, 30, NULL, NULL, &ipg_clk);
563DEFINE_CLOCK(cspi1_clk1, 0, PCCR0, 31, NULL, NULL, &ipg_clk);
564
565DEFINE_CLOCK(mstick_clk, 0, PCCR1, 2, NULL, &mstick_clk1, &ipg_clk);
566DEFINE_CLOCK(nfc_clk, 0, PCCR1, 3, get_rate_nfc, NULL, &cpu_clk);
567DEFINE_CLOCK(ssi2_clk, 1, PCCR1, 4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk);
568DEFINE_CLOCK(ssi1_clk, 0, PCCR1, 5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk);
569DEFINE_CLOCK(vpu_clk, 0, PCCR1, 6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk);
570DEFINE_CLOCK1(per4_clk, 3, PCCR1, 7, per, NULL, &mpll_main2_clk);
571DEFINE_CLOCK1(per3_clk, 2, PCCR1, 8, per, NULL, &mpll_main2_clk);
572DEFINE_CLOCK1(per2_clk, 1, PCCR1, 9, per, NULL, &mpll_main2_clk);
573DEFINE_CLOCK1(per1_clk, 0, PCCR1, 10, per, NULL, &mpll_main2_clk);
574DEFINE_CLOCK(usb_clk1, 0, PCCR1, 11, NULL, NULL, &ahb_clk);
575DEFINE_CLOCK(slcdc_clk1, 0, PCCR1, 12, NULL, NULL, &ahb_clk);
576DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk);
577DEFINE_CLOCK(rtic_clk1, 0, PCCR1, 14, NULL, NULL, &ahb_clk);
578DEFINE_CLOCK(lcdc_clk2, 0, PCCR1, 15, NULL, NULL, &ahb_clk);
579DEFINE_CLOCK(vpu_clk1, 0, PCCR1, 16, NULL, NULL, &ahb_clk);
580DEFINE_CLOCK(fec_clk1, 0, PCCR1, 17, NULL, NULL, &ahb_clk);
581DEFINE_CLOCK(emma_clk1, 0, PCCR1, 18, NULL, NULL, &ahb_clk);
582DEFINE_CLOCK(emi_clk, 0, PCCR1, 19, NULL, NULL, &ahb_clk);
583DEFINE_CLOCK(dma_clk1, 0, PCCR1, 20, NULL, NULL, &ahb_clk);
584DEFINE_CLOCK(csi_clk1, 0, PCCR1, 21, NULL, NULL, &ahb_clk);
585DEFINE_CLOCK(brom_clk, 0, PCCR1, 22, NULL, NULL, &ahb_clk);
586DEFINE_CLOCK(ata_clk, 0, PCCR1, 23, NULL, NULL, &ahb_clk);
587DEFINE_CLOCK(wdog_clk, 0, PCCR1, 24, NULL, NULL, &ipg_clk);
588DEFINE_CLOCK(usb_clk, 0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk);
589DEFINE_CLOCK(uart6_clk1, 0, PCCR1, 26, NULL, NULL, &ipg_clk);
590DEFINE_CLOCK(uart5_clk1, 0, PCCR1, 27, NULL, NULL, &ipg_clk);
591DEFINE_CLOCK(uart4_clk1, 0, PCCR1, 28, NULL, NULL, &ipg_clk);
592DEFINE_CLOCK(uart3_clk1, 0, PCCR1, 29, NULL, NULL, &ipg_clk);
593DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk);
594DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk);
595
596/* Clocks we cannot directly gate, but drivers need their rates */
597DEFINE_CLOCK(cspi1_clk, 0, 0, 0, NULL, &cspi1_clk1, &per2_clk);
598DEFINE_CLOCK(cspi2_clk, 1, 0, 0, NULL, &cspi2_clk1, &per2_clk);
599DEFINE_CLOCK(cspi3_clk, 2, 0, 0, NULL, &cspi13_clk1, &per2_clk);
600DEFINE_CLOCK(sdhc1_clk, 0, 0, 0, NULL, &sdhc1_clk1, &per2_clk);
601DEFINE_CLOCK(sdhc2_clk, 1, 0, 0, NULL, &sdhc2_clk1, &per2_clk);
602DEFINE_CLOCK(sdhc3_clk, 2, 0, 0, NULL, &sdhc3_clk1, &per2_clk);
603DEFINE_CLOCK(pwm_clk, 0, 0, 0, NULL, &pwm_clk1, &per1_clk);
604DEFINE_CLOCK(gpt1_clk, 0, 0, 0, NULL, &gpt1_clk1, &per1_clk);
605DEFINE_CLOCK(gpt2_clk, 1, 0, 0, NULL, &gpt2_clk1, &per1_clk);
606DEFINE_CLOCK(gpt3_clk, 2, 0, 0, NULL, &gpt3_clk1, &per1_clk);
607DEFINE_CLOCK(gpt4_clk, 3, 0, 0, NULL, &gpt4_clk1, &per1_clk);
608DEFINE_CLOCK(gpt5_clk, 4, 0, 0, NULL, &gpt5_clk1, &per1_clk);
609DEFINE_CLOCK(gpt6_clk, 5, 0, 0, NULL, &gpt6_clk1, &per1_clk);
610DEFINE_CLOCK(uart1_clk, 0, 0, 0, NULL, &uart1_clk1, &per1_clk);
611DEFINE_CLOCK(uart2_clk, 1, 0, 0, NULL, &uart2_clk1, &per1_clk);
612DEFINE_CLOCK(uart3_clk, 2, 0, 0, NULL, &uart3_clk1, &per1_clk);
613DEFINE_CLOCK(uart4_clk, 3, 0, 0, NULL, &uart4_clk1, &per1_clk);
614DEFINE_CLOCK(uart5_clk, 4, 0, 0, NULL, &uart5_clk1, &per1_clk);
615DEFINE_CLOCK(uart6_clk, 5, 0, 0, NULL, &uart6_clk1, &per1_clk);
616DEFINE_CLOCK1(lcdc_clk, 0, 0, 0, parent, &lcdc_clk1, &per3_clk);
617DEFINE_CLOCK1(csi_clk, 0, 0, 0, parent, &csi_clk1, &per4_clk);
618
619#define _REGISTER_CLOCK(d, n, c) \
620 { \
621 .dev_id = d, \
622 .con_id = n, \
623 .clk = &c, \
624 },
625
626static struct clk_lookup lookups[] = {
627 _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
628 _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
629 _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
630 _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
631 _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
632 _REGISTER_CLOCK("imx-uart.5", NULL, uart6_clk)
633 _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk)
634 _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk)
635 _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk)
636 _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk)
637 _REGISTER_CLOCK(NULL, "gpt5", gpt5_clk)
638 _REGISTER_CLOCK(NULL, "gpt6", gpt6_clk)
639 _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk)
640 _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
641 _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
642 _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
643 _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
644 _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
645 _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
646 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
647 _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
648 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
649 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1)
650 _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk)
651 _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk1)
652 _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk)
653 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1)
654 _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk)
655 _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1)
656 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
657 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
658 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
659 _REGISTER_CLOCK(NULL, "vpu", vpu_clk)
660 _REGISTER_CLOCK(NULL, "dma", dma_clk)
661 _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
662 _REGISTER_CLOCK(NULL, "brom", brom_clk)
663 _REGISTER_CLOCK(NULL, "emma", emma_clk)
664 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
665 _REGISTER_CLOCK("fec.0", NULL, fec_clk)
666 _REGISTER_CLOCK(NULL, "emi", emi_clk)
667 _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
668 _REGISTER_CLOCK(NULL, "ata", ata_clk)
669 _REGISTER_CLOCK(NULL, "mstick", mstick_clk)
670 _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
671 _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
672 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
673 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
674 _REGISTER_CLOCK(NULL, "iim", iim_clk)
675 _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
676 _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
677 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
678 _REGISTER_CLOCK(NULL, "scc", scc_clk)
679};
680
681/* Adjust the clock path for TO2 and later */
682static void __init to2_adjust_clocks(void)
683{
684 unsigned long cscr = __raw_readl(CCM_CSCR);
685
686 if (mx27_revision() >= CHIP_REV_2_0) {
687 if (cscr & CCM_CSCR_ARM_SRC)
688 cpu_clk.parent = &mpll_main1_clk;
689
690 if (!(cscr & CCM_CSCR_SSI2))
691 ssi1_clk.parent = &spll_clk;
692
693 if (!(cscr & CCM_CSCR_SSI1))
694 ssi1_clk.parent = &spll_clk;
695
696 if (!(cscr & CCM_CSCR_VPU))
697 vpu_clk.parent = &spll_clk;
698 } else {
699 cpu_clk.parent = &mpll_clk;
700 cpu_clk.set_parent = NULL;
701 cpu_clk.round_rate = NULL;
702 cpu_clk.set_rate = NULL;
703 ahb_clk.parent = &mpll_clk;
704
705 per1_clk.parent = &mpll_clk;
706 per2_clk.parent = &mpll_clk;
707 per3_clk.parent = &mpll_clk;
708 per4_clk.parent = &mpll_clk;
709
710 ssi1_clk.parent = &mpll_clk;
711 ssi2_clk.parent = &mpll_clk;
712
713 vpu_clk.parent = &mpll_clk;
714 }
715}
716
717/*
718 * must be called very early to get information about the
719 * available clock rate when the timer framework starts
720 */
721int __init mx27_clocks_init(unsigned long fref)
722{
723 u32 cscr = __raw_readl(CCM_CSCR);
724
725 external_high_reference = fref;
726
727 /* detect clock reference for both system PLLs */
728 if (cscr & CCM_CSCR_MCU)
729 mpll_clk.parent = &ckih_clk;
730 else
731 mpll_clk.parent = &fpm_clk;
732
733 if (cscr & CCM_CSCR_SP)
734 spll_clk.parent = &ckih_clk;
735 else
736 spll_clk.parent = &fpm_clk;
737
738 to2_adjust_clocks();
739
740 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
741
742 /* Turn off all clocks we do not need */
743 __raw_writel(0, CCM_PCCR0);
744 __raw_writel((1 << 10) | (1 << 19), CCM_PCCR1);
745
746 spll_clk.disable(&spll_clk);
747
748 /* enable basic clocks */
749 clk_enable(&per1_clk);
750 clk_enable(&gpio_clk);
751 clk_enable(&emi_clk);
752 clk_enable(&iim_clk);
753
754#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
755 clk_enable(&uart1_clk);
756#endif
757
758 mxc_timer_init(&gpt1_clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
759 MX27_INT_GPT1);
760
761 return 0;
762}
763
diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c
new file mode 100644
index 000000000000..d8d3b2d84dc5
--- /dev/null
+++ b/arch/arm/mach-imx/cpu-imx27.c
@@ -0,0 +1,64 @@
1/*
2 * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301, USA.
18 */
19
20/*
21 * i.MX27 specific CPU detection code
22 */
23
24#include <linux/io.h>
25#include <linux/module.h>
26
27#include <mach/hardware.h>
28
29static int cpu_silicon_rev = -1;
30static int cpu_partnumber;
31
32#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
33
34static void query_silicon_parameter(void)
35{
36 u32 val;
37 /*
38 * now we have access to the IO registers. As we need
39 * the silicon revision very early we read it here to
40 * avoid any further hooks
41 */
42 val = __raw_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR
43 + SYS_CHIP_ID));
44
45 cpu_silicon_rev = (int)(val >> 28);
46 cpu_partnumber = (int)((val >> 12) & 0xFFFF);
47}
48
49/*
50 * Returns:
51 * the silicon revision of the cpu
52 * -EINVAL - not a mx27
53 */
54int mx27_revision(void)
55{
56 if (cpu_silicon_rev == -1)
57 query_silicon_parameter();
58
59 if (cpu_partnumber != 0x8821)
60 return -EINVAL;
61
62 return cpu_silicon_rev;
63}
64EXPORT_SYMBOL(mx27_revision);
diff --git a/arch/arm/mach-imx/devices-imx1.h b/arch/arm/mach-imx/devices-imx1.h
new file mode 100644
index 000000000000..a8d94f078196
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx1.h
@@ -0,0 +1,18 @@
1/*
2 * Copyright (C) 2010 Pengutronix
3 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 */
9#include <mach/mx1.h>
10#include <mach/devices-common.h>
11
12#define imx1_add_i2c_imx(pdata) \
13 imx_add_imx_i2c(0, MX1_I2C_BASE_ADDR, SZ_4K, MX1_INT_I2C, pdata)
14
15#define imx1_add_imx_uart0(pdata) \
16 imx_add_imx_uart_3irq(0, MX1_UART1_BASE_ADDR, 0xd0, MX1_INT_UART1RX, MX1_INT_UART1TX, MX1_INT_UART1RTS, pdata)
17#define imx1_add_imx_uart1(pdata) \
18 imx_add_imx_uart_3irq(0, MX1_UART2_BASE_ADDR, 0xd0, MX1_INT_UART2RX, MX1_INT_UART2TX, MX1_INT_UART2RTS, pdata)
diff --git a/arch/arm/mach-imx/devices-imx21.h b/arch/arm/mach-imx/devices-imx21.h
new file mode 100644
index 000000000000..42788e99d127
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx21.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2010 Pengutronix
3 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 */
9#include <mach/mx21.h>
10#include <mach/devices-common.h>
11
12#define imx21_add_i2c_imx(pdata) \
13 imx_add_imx_i2c(0, MX2x_I2C_BASE_ADDR, SZ_4K, MX2x_INT_I2C, pdata)
14
15#define imx21_add_imx_uart0(pdata) \
16 imx_add_imx_uart_1irq(0, MX21_UART1_BASE_ADDR, SZ_4K, MX21_INT_UART1, pdata)
17#define imx21_add_imx_uart1(pdata) \
18 imx_add_imx_uart_1irq(1, MX21_UART2_BASE_ADDR, SZ_4K, MX21_INT_UART2, pdata)
19#define imx21_add_imx_uart2(pdata) \
20 imx_add_imx_uart_1irq(2, MX21_UART3_BASE_ADDR, SZ_4K, MX21_INT_UART3, pdata)
21#define imx21_add_imx_uart3(pdata) \
22 imx_add_imx_uart_1irq(3, MX21_UART4_BASE_ADDR, SZ_4K, MX21_INT_UART4, pdata)
23
24#define imx21_add_mxc_nand(pdata) \
25 imx_add_mxc_nand_v1(MX21_NFC_BASE_ADDR, MX21_INT_NANDFC, pdata)
26
27#define imx21_add_spi_imx0(pdata) \
28 imx_add_spi_imx(0, MX21_CSPI1_BASE_ADDR, SZ_4K, MX21_INT_CSPI1, pdata)
29#define imx21_add_spi_imx1(pdata) \
30 imx_add_spi_imx(1, MX21_CSPI2_BASE_ADDR, SZ_4K, MX21_INT_CSPI2, pdata)
diff --git a/arch/arm/mach-imx/devices-imx27.h b/arch/arm/mach-imx/devices-imx27.h
new file mode 100644
index 000000000000..65e7bb7ec2e8
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx27.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (C) 2010 Pengutronix
3 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 */
9#include <mach/mx27.h>
10#include <mach/devices-common.h>
11
12#define imx27_add_i2c_imx0(pdata) \
13 imx_add_imx_i2c(0, MX27_I2C1_BASE_ADDR, SZ_4K, MX27_INT_I2C1, pdata)
14#define imx27_add_i2c_imx1(pdata) \
15 imx_add_imx_i2c(1, MX27_I2C2_BASE_ADDR, SZ_4K, MX27_INT_I2C2, pdata)
16
17#define imx27_add_imx_uart0(pdata) \
18 imx_add_imx_uart_1irq(0, MX27_UART1_BASE_ADDR, SZ_4K, MX27_INT_UART1, pdata)
19#define imx27_add_imx_uart1(pdata) \
20 imx_add_imx_uart_1irq(1, MX27_UART2_BASE_ADDR, SZ_4K, MX27_INT_UART2, pdata)
21#define imx27_add_imx_uart2(pdata) \
22 imx_add_imx_uart_1irq(2, MX27_UART3_BASE_ADDR, SZ_4K, MX27_INT_UART3, pdata)
23#define imx27_add_imx_uart3(pdata) \
24 imx_add_imx_uart_1irq(3, MX27_UART4_BASE_ADDR, SZ_4K, MX27_INT_UART4, pdata)
25#define imx27_add_imx_uart4(pdata) \
26 imx_add_imx_uart_1irq(4, MX27_UART5_BASE_ADDR, SZ_4K, MX27_INT_UART5, pdata)
27#define imx27_add_imx_uart5(pdata) \
28 imx_add_imx_uart_1irq(5, MX27_UART6_BASE_ADDR, SZ_4K, MX27_INT_UART6, pdata)
29
30#define imx27_add_mxc_nand(pdata) \
31 imx_add_mxc_nand_v1(MX27_NFC_BASE_ADDR, MX27_INT_NANDFC, pdata)
32
33#define imx27_add_spi_imx0(pdata) \
34 imx_add_spi_imx(0, MX27_CSPI1_BASE_ADDR, SZ_4K, MX27_INT_CSPI1, pdata)
35#define imx27_add_spi_imx1(pdata) \
36 imx_add_spi_imx(1, MX27_CSPI2_BASE_ADDR, SZ_4K, MX27_INT_CSPI2, pdata)
37#define imx27_add_spi_imx2(pdata) \
38 imx_add_spi_imx(2, MX27_CSPI3_BASE_ADDR, SZ_4K, MX27_INT_CSPI3, pdata)
diff --git a/arch/arm/mach-imx/devices.c b/arch/arm/mach-imx/devices.c
new file mode 100644
index 000000000000..9c271a752b84
--- /dev/null
+++ b/arch/arm/mach-imx/devices.c
@@ -0,0 +1,609 @@
1/*
2 * Author: MontaVista Software, Inc.
3 * <source@mvista.com>
4 *
5 * Based on the OMAP devices.c
6 *
7 * 2005 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 *
12 * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
13 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
14 * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
15 * Copyright (c) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
16 * Copyright (c) 2008 Darius Augulis <darius.augulis@teltonika.lt>
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
30 * MA 02110-1301, USA.
31 */
32#include <linux/module.h>
33#include <linux/kernel.h>
34#include <linux/init.h>
35#include <linux/platform_device.h>
36#include <linux/gpio.h>
37#include <linux/dma-mapping.h>
38#include <linux/serial.h>
39
40#include <mach/irqs.h>
41#include <mach/hardware.h>
42#include <mach/common.h>
43#include <mach/mmc.h>
44
45#include "devices.h"
46
47#if defined(CONFIG_ARCH_MX1)
48static struct resource imx1_camera_resources[] = {
49 {
50 .start = 0x00224000,
51 .end = 0x00224010,
52 .flags = IORESOURCE_MEM,
53 }, {
54 .start = MX1_CSI_INT,
55 .end = MX1_CSI_INT,
56 .flags = IORESOURCE_IRQ,
57 },
58};
59
60static u64 imx1_camera_dmamask = DMA_BIT_MASK(32);
61
62struct platform_device imx1_camera_device = {
63 .name = "mx1-camera",
64 .id = 0, /* This is used to put cameras on this interface */
65 .dev = {
66 .dma_mask = &imx1_camera_dmamask,
67 .coherent_dma_mask = DMA_BIT_MASK(32),
68 },
69 .resource = imx1_camera_resources,
70 .num_resources = ARRAY_SIZE(imx1_camera_resources),
71};
72
73static struct resource imx_rtc_resources[] = {
74 {
75 .start = 0x00204000,
76 .end = 0x00204024,
77 .flags = IORESOURCE_MEM,
78 }, {
79 .start = MX1_RTC_INT,
80 .end = MX1_RTC_INT,
81 .flags = IORESOURCE_IRQ,
82 }, {
83 .start = MX1_RTC_SAMINT,
84 .end = MX1_RTC_SAMINT,
85 .flags = IORESOURCE_IRQ,
86 },
87};
88
89struct platform_device imx_rtc_device = {
90 .name = "rtc-imx",
91 .id = 0,
92 .resource = imx_rtc_resources,
93 .num_resources = ARRAY_SIZE(imx_rtc_resources),
94};
95
96static struct resource imx_wdt_resources[] = {
97 {
98 .start = 0x00201000,
99 .end = 0x00201008,
100 .flags = IORESOURCE_MEM,
101 }, {
102 .start = MX1_WDT_INT,
103 .end = MX1_WDT_INT,
104 .flags = IORESOURCE_IRQ,
105 },
106};
107
108struct platform_device imx_wdt_device = {
109 .name = "imx-wdt",
110 .id = 0,
111 .resource = imx_wdt_resources,
112 .num_resources = ARRAY_SIZE(imx_wdt_resources),
113};
114
115static struct resource imx_usb_resources[] = {
116 {
117 .start = 0x00212000,
118 .end = 0x00212148,
119 .flags = IORESOURCE_MEM,
120 }, {
121 .start = MX1_USBD_INT0,
122 .end = MX1_USBD_INT0,
123 .flags = IORESOURCE_IRQ,
124 }, {
125 .start = MX1_USBD_INT1,
126 .end = MX1_USBD_INT1,
127 .flags = IORESOURCE_IRQ,
128 }, {
129 .start = MX1_USBD_INT2,
130 .end = MX1_USBD_INT2,
131 .flags = IORESOURCE_IRQ,
132 }, {
133 .start = MX1_USBD_INT3,
134 .end = MX1_USBD_INT3,
135 .flags = IORESOURCE_IRQ,
136 }, {
137 .start = MX1_USBD_INT4,
138 .end = MX1_USBD_INT4,
139 .flags = IORESOURCE_IRQ,
140 }, {
141 .start = MX1_USBD_INT5,
142 .end = MX1_USBD_INT5,
143 .flags = IORESOURCE_IRQ,
144 }, {
145 .start = MX1_USBD_INT6,
146 .end = MX1_USBD_INT6,
147 .flags = IORESOURCE_IRQ,
148 },
149};
150
151struct platform_device imx_usb_device = {
152 .name = "imx_udc",
153 .id = 0,
154 .num_resources = ARRAY_SIZE(imx_usb_resources),
155 .resource = imx_usb_resources,
156};
157
158/* GPIO port description */
159static struct mxc_gpio_port imx_gpio_ports[] = {
160 {
161 .chip.label = "gpio-0",
162 .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR),
163 .irq = MX1_GPIO_INT_PORTA,
164 .virtual_irq_start = MXC_GPIO_IRQ_START,
165 }, {
166 .chip.label = "gpio-1",
167 .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x100),
168 .irq = MX1_GPIO_INT_PORTB,
169 .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
170 }, {
171 .chip.label = "gpio-2",
172 .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x200),
173 .irq = MX1_GPIO_INT_PORTC,
174 .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
175 }, {
176 .chip.label = "gpio-3",
177 .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x300),
178 .irq = MX1_GPIO_INT_PORTD,
179 .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
180 }
181};
182
183int __init imx1_register_gpios(void)
184{
185 return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
186}
187#endif
188
189#if defined(CONFIG_MACH_MX21) || defined(CONFIG_MACH_MX27)
190
191#ifdef CONFIG_MACH_MX27
192static struct resource mx27_camera_resources[] = {
193 {
194 .start = MX27_CSI_BASE_ADDR,
195 .end = MX27_CSI_BASE_ADDR + 0x1f,
196 .flags = IORESOURCE_MEM,
197 }, {
198 .start = MX27_EMMA_PRP_BASE_ADDR,
199 .end = MX27_EMMA_PRP_BASE_ADDR + 0x1f,
200 .flags = IORESOURCE_MEM,
201 }, {
202 .start = MX27_INT_CSI,
203 .end = MX27_INT_CSI,
204 .flags = IORESOURCE_IRQ,
205 },{
206 .start = MX27_INT_EMMAPRP,
207 .end = MX27_INT_EMMAPRP,
208 .flags = IORESOURCE_IRQ,
209 },
210};
211struct platform_device mx27_camera_device = {
212 .name = "mx2-camera",
213 .id = 0,
214 .num_resources = ARRAY_SIZE(mx27_camera_resources),
215 .resource = mx27_camera_resources,
216 .dev = {
217 .coherent_dma_mask = 0xffffffff,
218 },
219};
220#endif
221
222/*
223 * General Purpose Timer
224 * - i.MX21: 3 timers
225 * - i.MX27: 6 timers
226 */
227#define DEFINE_IMX_GPT_DEVICE(n, baseaddr, irq) \
228 static struct resource timer ## n ##_resources[] = { \
229 { \
230 .start = baseaddr, \
231 .end = baseaddr + SZ_4K - 1, \
232 .flags = IORESOURCE_MEM, \
233 }, { \
234 .start = irq, \
235 .end = irq, \
236 .flags = IORESOURCE_IRQ, \
237 } \
238 }; \
239 \
240 struct platform_device mxc_gpt ## n = { \
241 .name = "imx_gpt", \
242 .id = n, \
243 .num_resources = ARRAY_SIZE(timer ## n ## _resources), \
244 .resource = timer ## n ## _resources, \
245 }
246
247/* We use gpt1 as system timer, so do not add a device for this one */
248DEFINE_IMX_GPT_DEVICE(1, MX2x_GPT2_BASE_ADDR, MX2x_INT_GPT2);
249DEFINE_IMX_GPT_DEVICE(2, MX2x_GPT3_BASE_ADDR, MX2x_INT_GPT3);
250
251#ifdef CONFIG_MACH_MX27
252DEFINE_IMX_GPT_DEVICE(3, MX27_GPT4_BASE_ADDR, MX27_INT_GPT4);
253DEFINE_IMX_GPT_DEVICE(4, MX27_GPT5_BASE_ADDR, MX27_INT_GPT5);
254DEFINE_IMX_GPT_DEVICE(5, MX27_GPT6_BASE_ADDR, MX27_INT_GPT6);
255#endif
256
257/* Watchdog: i.MX1 has seperate driver, i.MX21 and i.MX27 are equal */
258static struct resource mxc_wdt_resources[] = {
259 {
260 .start = MX2x_WDOG_BASE_ADDR,
261 .end = MX2x_WDOG_BASE_ADDR + SZ_4K - 1,
262 .flags = IORESOURCE_MEM,
263 },
264};
265
266struct platform_device mxc_wdt = {
267 .name = "imx2-wdt",
268 .id = 0,
269 .num_resources = ARRAY_SIZE(mxc_wdt_resources),
270 .resource = mxc_wdt_resources,
271};
272
273static struct resource mxc_w1_master_resources[] = {
274 {
275 .start = MX2x_OWIRE_BASE_ADDR,
276 .end = MX2x_OWIRE_BASE_ADDR + SZ_4K - 1,
277 .flags = IORESOURCE_MEM,
278 },
279};
280
281struct platform_device mxc_w1_master_device = {
282 .name = "mxc_w1",
283 .id = 0,
284 .num_resources = ARRAY_SIZE(mxc_w1_master_resources),
285 .resource = mxc_w1_master_resources,
286};
287
288/*
289 * lcdc:
290 * - i.MX1: the basic controller
291 * - i.MX21: to be checked
292 * - i.MX27: like i.MX1, with slightly variations
293 */
294static struct resource mxc_fb[] = {
295 {
296 .start = MX2x_LCDC_BASE_ADDR,
297 .end = MX2x_LCDC_BASE_ADDR + SZ_4K - 1,
298 .flags = IORESOURCE_MEM,
299 }, {
300 .start = MX2x_INT_LCDC,
301 .end = MX2x_INT_LCDC,
302 .flags = IORESOURCE_IRQ,
303 }
304};
305
306/* mxc lcd driver */
307struct platform_device mxc_fb_device = {
308 .name = "imx-fb",
309 .id = 0,
310 .num_resources = ARRAY_SIZE(mxc_fb),
311 .resource = mxc_fb,
312 .dev = {
313 .coherent_dma_mask = DMA_BIT_MASK(32),
314 },
315};
316
317#ifdef CONFIG_MACH_MX27
318static struct resource mxc_fec_resources[] = {
319 {
320 .start = MX27_FEC_BASE_ADDR,
321 .end = MX27_FEC_BASE_ADDR + SZ_4K - 1,
322 .flags = IORESOURCE_MEM,
323 }, {
324 .start = MX27_INT_FEC,
325 .end = MX27_INT_FEC,
326 .flags = IORESOURCE_IRQ,
327 },
328};
329
330struct platform_device mxc_fec_device = {
331 .name = "fec",
332 .id = 0,
333 .num_resources = ARRAY_SIZE(mxc_fec_resources),
334 .resource = mxc_fec_resources,
335};
336#endif
337
338static struct resource mxc_pwm_resources[] = {
339 {
340 .start = MX2x_PWM_BASE_ADDR,
341 .end = MX2x_PWM_BASE_ADDR + SZ_4K - 1,
342 .flags = IORESOURCE_MEM,
343 }, {
344 .start = MX2x_INT_PWM,
345 .end = MX2x_INT_PWM,
346 .flags = IORESOURCE_IRQ,
347 }
348};
349
350struct platform_device mxc_pwm_device = {
351 .name = "mxc_pwm",
352 .id = 0,
353 .num_resources = ARRAY_SIZE(mxc_pwm_resources),
354 .resource = mxc_pwm_resources,
355};
356
357#define DEFINE_MXC_MMC_DEVICE(n, baseaddr, irq, dmareq) \
358 static struct resource mxc_sdhc_resources ## n[] = { \
359 { \
360 .start = baseaddr, \
361 .end = baseaddr + SZ_4K - 1, \
362 .flags = IORESOURCE_MEM, \
363 }, { \
364 .start = irq, \
365 .end = irq, \
366 .flags = IORESOURCE_IRQ, \
367 }, { \
368 .start = dmareq, \
369 .end = dmareq, \
370 .flags = IORESOURCE_DMA, \
371 }, \
372 }; \
373 \
374 static u64 mxc_sdhc ## n ## _dmamask = DMA_BIT_MASK(32); \
375 \
376 struct platform_device mxc_sdhc_device ## n = { \
377 .name = "mxc-mmc", \
378 .id = n, \
379 .dev = { \
380 .dma_mask = &mxc_sdhc ## n ## _dmamask, \
381 .coherent_dma_mask = DMA_BIT_MASK(32), \
382 }, \
383 .num_resources = ARRAY_SIZE(mxc_sdhc_resources ## n), \
384 .resource = mxc_sdhc_resources ## n, \
385 }
386
387DEFINE_MXC_MMC_DEVICE(0, MX2x_SDHC1_BASE_ADDR, MX2x_INT_SDHC1, MX2x_DMA_REQ_SDHC1);
388DEFINE_MXC_MMC_DEVICE(1, MX2x_SDHC2_BASE_ADDR, MX2x_INT_SDHC2, MX2x_DMA_REQ_SDHC2);
389
390#ifdef CONFIG_MACH_MX27
391static struct resource otg_resources[] = {
392 {
393 .start = MX27_USBOTG_BASE_ADDR,
394 .end = MX27_USBOTG_BASE_ADDR + 0x1ff,
395 .flags = IORESOURCE_MEM,
396 }, {
397 .start = MX27_INT_USB3,
398 .end = MX27_INT_USB3,
399 .flags = IORESOURCE_IRQ,
400 },
401};
402
403static u64 otg_dmamask = DMA_BIT_MASK(32);
404
405/* OTG gadget device */
406struct platform_device mxc_otg_udc_device = {
407 .name = "fsl-usb2-udc",
408 .id = -1,
409 .dev = {
410 .dma_mask = &otg_dmamask,
411 .coherent_dma_mask = DMA_BIT_MASK(32),
412 },
413 .resource = otg_resources,
414 .num_resources = ARRAY_SIZE(otg_resources),
415};
416
417/* OTG host */
418struct platform_device mxc_otg_host = {
419 .name = "mxc-ehci",
420 .id = 0,
421 .dev = {
422 .coherent_dma_mask = DMA_BIT_MASK(32),
423 .dma_mask = &otg_dmamask,
424 },
425 .resource = otg_resources,
426 .num_resources = ARRAY_SIZE(otg_resources),
427};
428
429/* USB host 1 */
430
431static u64 usbh1_dmamask = DMA_BIT_MASK(32);
432
433static struct resource mxc_usbh1_resources[] = {
434 {
435 .start = MX27_USBOTG_BASE_ADDR + 0x200,
436 .end = MX27_USBOTG_BASE_ADDR + 0x3ff,
437 .flags = IORESOURCE_MEM,
438 }, {
439 .start = MX27_INT_USB1,
440 .end = MX27_INT_USB1,
441 .flags = IORESOURCE_IRQ,
442 },
443};
444
445struct platform_device mxc_usbh1 = {
446 .name = "mxc-ehci",
447 .id = 1,
448 .dev = {
449 .coherent_dma_mask = DMA_BIT_MASK(32),
450 .dma_mask = &usbh1_dmamask,
451 },
452 .resource = mxc_usbh1_resources,
453 .num_resources = ARRAY_SIZE(mxc_usbh1_resources),
454};
455
456/* USB host 2 */
457static u64 usbh2_dmamask = DMA_BIT_MASK(32);
458
459static struct resource mxc_usbh2_resources[] = {
460 {
461 .start = MX27_USBOTG_BASE_ADDR + 0x400,
462 .end = MX27_USBOTG_BASE_ADDR + 0x5ff,
463 .flags = IORESOURCE_MEM,
464 }, {
465 .start = MX27_INT_USB2,
466 .end = MX27_INT_USB2,
467 .flags = IORESOURCE_IRQ,
468 },
469};
470
471struct platform_device mxc_usbh2 = {
472 .name = "mxc-ehci",
473 .id = 2,
474 .dev = {
475 .coherent_dma_mask = DMA_BIT_MASK(32),
476 .dma_mask = &usbh2_dmamask,
477 },
478 .resource = mxc_usbh2_resources,
479 .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
480};
481#endif
482
483#define DEFINE_IMX_SSI_DMARES(_name, ssin, suffix) \
484 { \
485 .name = _name, \
486 .start = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
487 .end = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
488 .flags = IORESOURCE_DMA, \
489 }
490
491#define DEFINE_IMX_SSI_DEVICE(n, ssin, baseaddr, irq) \
492 static struct resource imx_ssi_resources ## n[] = { \
493 { \
494 .start = MX2x_SSI ## ssin ## _BASE_ADDR, \
495 .end = MX2x_SSI ## ssin ## _BASE_ADDR + 0x6f, \
496 .flags = IORESOURCE_MEM, \
497 }, { \
498 .start = MX2x_INT_SSI1, \
499 .end = MX2x_INT_SSI1, \
500 .flags = IORESOURCE_IRQ, \
501 }, \
502 DEFINE_IMX_SSI_DMARES("tx0", ssin, TX0), \
503 DEFINE_IMX_SSI_DMARES("rx0", ssin, RX0), \
504 DEFINE_IMX_SSI_DMARES("tx1", ssin, TX1), \
505 DEFINE_IMX_SSI_DMARES("rx1", ssin, RX1), \
506 }; \
507 \
508 struct platform_device imx_ssi_device ## n = { \
509 .name = "imx-ssi", \
510 .id = n, \
511 .num_resources = ARRAY_SIZE(imx_ssi_resources ## n), \
512 .resource = imx_ssi_resources ## n, \
513 }
514
515DEFINE_IMX_SSI_DEVICE(0, 1, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
516DEFINE_IMX_SSI_DEVICE(1, 2, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
517
518/* GPIO port description */
519#define DEFINE_MXC_GPIO_PORT_IRQ(SOC, n, _irq) \
520 { \
521 .chip.label = "gpio-" #n, \
522 .irq = _irq, \
523 .base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR + \
524 n * 0x100), \
525 .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \
526 }
527
528#define DEFINE_MXC_GPIO_PORT(SOC, n) \
529 { \
530 .chip.label = "gpio-" #n, \
531 .base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR + \
532 n * 0x100), \
533 .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \
534 }
535
536#define DEFINE_MXC_GPIO_PORTS(SOC, pfx) \
537 static struct mxc_gpio_port pfx ## _gpio_ports[] = { \
538 DEFINE_MXC_GPIO_PORT_IRQ(SOC, 0, SOC ## _INT_GPIO), \
539 DEFINE_MXC_GPIO_PORT(SOC, 1), \
540 DEFINE_MXC_GPIO_PORT(SOC, 2), \
541 DEFINE_MXC_GPIO_PORT(SOC, 3), \
542 DEFINE_MXC_GPIO_PORT(SOC, 4), \
543 DEFINE_MXC_GPIO_PORT(SOC, 5), \
544 }
545
546#ifdef CONFIG_MACH_MX21
547DEFINE_MXC_GPIO_PORTS(MX21, imx21);
548
549int __init imx21_register_gpios(void)
550{
551 return mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports));
552}
553#endif
554
555#ifdef CONFIG_MACH_MX27
556DEFINE_MXC_GPIO_PORTS(MX27, imx27);
557
558int __init imx27_register_gpios(void)
559{
560 return mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports));
561}
562#endif
563
564#ifdef CONFIG_MACH_MX21
565static struct resource mx21_usbhc_resources[] = {
566 {
567 .start = MX21_USBOTG_BASE_ADDR,
568 .end = MX21_USBOTG_BASE_ADDR + SZ_8K - 1,
569 .flags = IORESOURCE_MEM,
570 },
571 {
572 .start = MX21_INT_USBHOST,
573 .end = MX21_INT_USBHOST,
574 .flags = IORESOURCE_IRQ,
575 },
576};
577
578struct platform_device mx21_usbhc_device = {
579 .name = "imx21-hcd",
580 .id = 0,
581 .dev = {
582 .dma_mask = &mx21_usbhc_device.dev.coherent_dma_mask,
583 .coherent_dma_mask = DMA_BIT_MASK(32),
584 },
585 .num_resources = ARRAY_SIZE(mx21_usbhc_resources),
586 .resource = mx21_usbhc_resources,
587};
588#endif
589
590static struct resource imx_kpp_resources[] = {
591 {
592 .start = MX2x_KPP_BASE_ADDR,
593 .end = MX2x_KPP_BASE_ADDR + 0xf,
594 .flags = IORESOURCE_MEM
595 }, {
596 .start = MX2x_INT_KPP,
597 .end = MX2x_INT_KPP,
598 .flags = IORESOURCE_IRQ,
599 },
600};
601
602struct platform_device imx_kpp_device = {
603 .name = "imx-keypad",
604 .id = -1,
605 .num_resources = ARRAY_SIZE(imx_kpp_resources),
606 .resource = imx_kpp_resources,
607};
608
609#endif
diff --git a/arch/arm/mach-imx/devices.h b/arch/arm/mach-imx/devices.h
new file mode 100644
index 000000000000..efd4527506a5
--- /dev/null
+++ b/arch/arm/mach-imx/devices.h
@@ -0,0 +1,32 @@
1#ifdef CONFIG_ARCH_MX1
2extern struct platform_device imx1_camera_device;
3extern struct platform_device imx_rtc_device;
4extern struct platform_device imx_wdt_device;
5extern struct platform_device imx_usb_device;
6#endif
7
8#if defined(CONFIG_MACH_MX21) || defined(CONFIG_MACH_MX27)
9extern struct platform_device mxc_gpt1;
10extern struct platform_device mxc_gpt2;
11#ifdef CONFIG_MACH_MX27
12extern struct platform_device mxc_gpt3;
13extern struct platform_device mxc_gpt4;
14extern struct platform_device mxc_gpt5;
15#endif
16extern struct platform_device mxc_wdt;
17extern struct platform_device mxc_w1_master_device;
18extern struct platform_device mxc_fb_device;
19extern struct platform_device mxc_fec_device;
20extern struct platform_device mxc_pwm_device;
21extern struct platform_device mxc_sdhc_device0;
22extern struct platform_device mxc_sdhc_device1;
23extern struct platform_device mxc_otg_udc_device;
24extern struct platform_device mx27_camera_device;
25extern struct platform_device mxc_otg_host;
26extern struct platform_device mxc_usbh1;
27extern struct platform_device mxc_usbh2;
28extern struct platform_device mx21_usbhc_device;
29extern struct platform_device imx_ssi_device0;
30extern struct platform_device imx_ssi_device1;
31extern struct platform_device imx_kpp_device;
32#endif
diff --git a/arch/arm/mach-imx/dma-v1.c b/arch/arm/mach-imx/dma-v1.c
new file mode 100644
index 000000000000..3e8c47c63bac
--- /dev/null
+++ b/arch/arm/mach-imx/dma-v1.c
@@ -0,0 +1,862 @@
1/*
2 * linux/arch/arm/plat-mxc/dma-v1.c
3 *
4 * i.MX DMA registration and IRQ dispatching
5 *
6 * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz>
7 * Copyright 2008 Juergen Beisert, <kernel@pengutronix.de>
8 * Copyright 2008 Sascha Hauer, <s.hauer@pengutronix.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 * MA 02110-1301, USA.
23 */
24
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/interrupt.h>
29#include <linux/errno.h>
30#include <linux/clk.h>
31#include <linux/scatterlist.h>
32#include <linux/io.h>
33
34#include <asm/system.h>
35#include <asm/irq.h>
36#include <mach/hardware.h>
37#include <mach/dma-v1.h>
38
39#define DMA_DCR 0x00 /* Control Register */
40#define DMA_DISR 0x04 /* Interrupt status Register */
41#define DMA_DIMR 0x08 /* Interrupt mask Register */
42#define DMA_DBTOSR 0x0c /* Burst timeout status Register */
43#define DMA_DRTOSR 0x10 /* Request timeout Register */
44#define DMA_DSESR 0x14 /* Transfer Error Status Register */
45#define DMA_DBOSR 0x18 /* Buffer overflow status Register */
46#define DMA_DBTOCR 0x1c /* Burst timeout control Register */
47#define DMA_WSRA 0x40 /* W-Size Register A */
48#define DMA_XSRA 0x44 /* X-Size Register A */
49#define DMA_YSRA 0x48 /* Y-Size Register A */
50#define DMA_WSRB 0x4c /* W-Size Register B */
51#define DMA_XSRB 0x50 /* X-Size Register B */
52#define DMA_YSRB 0x54 /* Y-Size Register B */
53#define DMA_SAR(x) (0x80 + ((x) << 6)) /* Source Address Registers */
54#define DMA_DAR(x) (0x84 + ((x) << 6)) /* Destination Address Registers */
55#define DMA_CNTR(x) (0x88 + ((x) << 6)) /* Count Registers */
56#define DMA_CCR(x) (0x8c + ((x) << 6)) /* Control Registers */
57#define DMA_RSSR(x) (0x90 + ((x) << 6)) /* Request source select Registers */
58#define DMA_BLR(x) (0x94 + ((x) << 6)) /* Burst length Registers */
59#define DMA_RTOR(x) (0x98 + ((x) << 6)) /* Request timeout Registers */
60#define DMA_BUCR(x) (0x98 + ((x) << 6)) /* Bus Utilization Registers */
61#define DMA_CCNR(x) (0x9C + ((x) << 6)) /* Channel counter Registers */
62
63#define DCR_DRST (1<<1)
64#define DCR_DEN (1<<0)
65#define DBTOCR_EN (1<<15)
66#define DBTOCR_CNT(x) ((x) & 0x7fff)
67#define CNTR_CNT(x) ((x) & 0xffffff)
68#define CCR_ACRPT (1<<14)
69#define CCR_DMOD_LINEAR (0x0 << 12)
70#define CCR_DMOD_2D (0x1 << 12)
71#define CCR_DMOD_FIFO (0x2 << 12)
72#define CCR_DMOD_EOBFIFO (0x3 << 12)
73#define CCR_SMOD_LINEAR (0x0 << 10)
74#define CCR_SMOD_2D (0x1 << 10)
75#define CCR_SMOD_FIFO (0x2 << 10)
76#define CCR_SMOD_EOBFIFO (0x3 << 10)
77#define CCR_MDIR_DEC (1<<9)
78#define CCR_MSEL_B (1<<8)
79#define CCR_DSIZ_32 (0x0 << 6)
80#define CCR_DSIZ_8 (0x1 << 6)
81#define CCR_DSIZ_16 (0x2 << 6)
82#define CCR_SSIZ_32 (0x0 << 4)
83#define CCR_SSIZ_8 (0x1 << 4)
84#define CCR_SSIZ_16 (0x2 << 4)
85#define CCR_REN (1<<3)
86#define CCR_RPT (1<<2)
87#define CCR_FRC (1<<1)
88#define CCR_CEN (1<<0)
89#define RTOR_EN (1<<15)
90#define RTOR_CLK (1<<14)
91#define RTOR_PSC (1<<13)
92
93/*
94 * struct imx_dma_channel - i.MX specific DMA extension
95 * @name: name specified by DMA client
96 * @irq_handler: client callback for end of transfer
97 * @err_handler: client callback for error condition
98 * @data: clients context data for callbacks
99 * @dma_mode: direction of the transfer %DMA_MODE_READ or %DMA_MODE_WRITE
100 * @sg: pointer to the actual read/written chunk for scatter-gather emulation
101 * @resbytes: total residual number of bytes to transfer
102 * (it can be lower or same as sum of SG mapped chunk sizes)
103 * @sgcount: number of chunks to be read/written
104 *
105 * Structure is used for IMX DMA processing. It would be probably good
106 * @struct dma_struct in the future for external interfacing and use
107 * @struct imx_dma_channel only as extension to it.
108 */
109
110struct imx_dma_channel {
111 const char *name;
112 void (*irq_handler) (int, void *);
113 void (*err_handler) (int, void *, int errcode);
114 void (*prog_handler) (int, void *, struct scatterlist *);
115 void *data;
116 unsigned int dma_mode;
117 struct scatterlist *sg;
118 unsigned int resbytes;
119 int dma_num;
120
121 int in_use;
122
123 u32 ccr_from_device;
124 u32 ccr_to_device;
125
126 struct timer_list watchdog;
127
128 int hw_chaining;
129};
130
131static void __iomem *imx_dmav1_baseaddr;
132
133static void imx_dmav1_writel(unsigned val, unsigned offset)
134{
135 __raw_writel(val, imx_dmav1_baseaddr + offset);
136}
137
138static unsigned imx_dmav1_readl(unsigned offset)
139{
140 return __raw_readl(imx_dmav1_baseaddr + offset);
141}
142
143static struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
144
145static struct clk *dma_clk;
146
147static int imx_dma_hw_chain(struct imx_dma_channel *imxdma)
148{
149 if (cpu_is_mx27())
150 return imxdma->hw_chaining;
151 else
152 return 0;
153}
154
155/*
156 * imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation
157 */
158static inline int imx_dma_sg_next(int channel, struct scatterlist *sg)
159{
160 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
161 unsigned long now;
162
163 if (!imxdma->name) {
164 printk(KERN_CRIT "%s: called for not allocated channel %d\n",
165 __func__, channel);
166 return 0;
167 }
168
169 now = min(imxdma->resbytes, sg->length);
170 if (imxdma->resbytes != IMX_DMA_LENGTH_LOOP)
171 imxdma->resbytes -= now;
172
173 if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
174 imx_dmav1_writel(sg->dma_address, DMA_DAR(channel));
175 else
176 imx_dmav1_writel(sg->dma_address, DMA_SAR(channel));
177
178 imx_dmav1_writel(now, DMA_CNTR(channel));
179
180 pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, "
181 "size 0x%08x\n", channel,
182 imx_dmav1_readl(DMA_DAR(channel)),
183 imx_dmav1_readl(DMA_SAR(channel)),
184 imx_dmav1_readl(DMA_CNTR(channel)));
185
186 return now;
187}
188
189/**
190 * imx_dma_setup_single - setup i.MX DMA channel for linear memory to/from
191 * device transfer
192 *
193 * @channel: i.MX DMA channel number
194 * @dma_address: the DMA/physical memory address of the linear data block
195 * to transfer
196 * @dma_length: length of the data block in bytes
197 * @dev_addr: physical device port address
198 * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
199 * or %DMA_MODE_WRITE from memory to the device
200 *
201 * Return value: if incorrect parameters are provided -%EINVAL.
202 * Zero indicates success.
203 */
204int
205imx_dma_setup_single(int channel, dma_addr_t dma_address,
206 unsigned int dma_length, unsigned int dev_addr,
207 unsigned int dmamode)
208{
209 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
210
211 imxdma->sg = NULL;
212 imxdma->dma_mode = dmamode;
213
214 if (!dma_address) {
215 printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n",
216 channel);
217 return -EINVAL;
218 }
219
220 if (!dma_length) {
221 printk(KERN_ERR "imxdma%d: imx_dma_setup_single zero length\n",
222 channel);
223 return -EINVAL;
224 }
225
226 if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
227 pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
228 "dev_addr=0x%08x for read\n",
229 channel, __func__, (unsigned int)dma_address,
230 dma_length, dev_addr);
231
232 imx_dmav1_writel(dev_addr, DMA_SAR(channel));
233 imx_dmav1_writel(dma_address, DMA_DAR(channel));
234 imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel));
235 } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
236 pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
237 "dev_addr=0x%08x for write\n",
238 channel, __func__, (unsigned int)dma_address,
239 dma_length, dev_addr);
240
241 imx_dmav1_writel(dma_address, DMA_SAR(channel));
242 imx_dmav1_writel(dev_addr, DMA_DAR(channel));
243 imx_dmav1_writel(imxdma->ccr_to_device,
244 DMA_CCR(channel));
245 } else {
246 printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n",
247 channel);
248 return -EINVAL;
249 }
250
251 imx_dmav1_writel(dma_length, DMA_CNTR(channel));
252
253 return 0;
254}
255EXPORT_SYMBOL(imx_dma_setup_single);
256
257/**
258 * imx_dma_setup_sg - setup i.MX DMA channel SG list to/from device transfer
259 * @channel: i.MX DMA channel number
260 * @sg: pointer to the scatter-gather list/vector
261 * @sgcount: scatter-gather list hungs count
262 * @dma_length: total length of the transfer request in bytes
263 * @dev_addr: physical device port address
264 * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
265 * or %DMA_MODE_WRITE from memory to the device
266 *
267 * The function sets up DMA channel state and registers to be ready for
268 * transfer specified by provided parameters. The scatter-gather emulation
269 * is set up according to the parameters.
270 *
271 * The full preparation of the transfer requires setup of more register
272 * by the caller before imx_dma_enable() can be called.
273 *
274 * %BLR(channel) holds transfer burst length in bytes, 0 means 64 bytes
275 *
276 * %RSSR(channel) has to be set to the DMA request line source %DMA_REQ_xxx
277 *
278 * %CCR(channel) has to specify transfer parameters, the next settings is
279 * typical for linear or simple scatter-gather transfers if %DMA_MODE_READ is
280 * specified
281 *
282 * %CCR_DMOD_LINEAR | %CCR_DSIZ_32 | %CCR_SMOD_FIFO | %CCR_SSIZ_x
283 *
284 * The typical setup for %DMA_MODE_WRITE is specified by next options
285 * combination
286 *
287 * %CCR_SMOD_LINEAR | %CCR_SSIZ_32 | %CCR_DMOD_FIFO | %CCR_DSIZ_x
288 *
289 * Be careful here and do not mistakenly mix source and target device
290 * port sizes constants, they are really different:
291 * %CCR_SSIZ_8, %CCR_SSIZ_16, %CCR_SSIZ_32,
292 * %CCR_DSIZ_8, %CCR_DSIZ_16, %CCR_DSIZ_32
293 *
294 * Return value: if incorrect parameters are provided -%EINVAL.
295 * Zero indicates success.
296 */
297int
298imx_dma_setup_sg(int channel,
299 struct scatterlist *sg, unsigned int sgcount,
300 unsigned int dma_length, unsigned int dev_addr,
301 unsigned int dmamode)
302{
303 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
304
305 if (imxdma->in_use)
306 return -EBUSY;
307
308 imxdma->sg = sg;
309 imxdma->dma_mode = dmamode;
310 imxdma->resbytes = dma_length;
311
312 if (!sg || !sgcount) {
313 printk(KERN_ERR "imxdma%d: imx_dma_setup_sg empty sg list\n",
314 channel);
315 return -EINVAL;
316 }
317
318 if (!sg->length) {
319 printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n",
320 channel);
321 return -EINVAL;
322 }
323
324 if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
325 pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
326 "dev_addr=0x%08x for read\n",
327 channel, __func__, sg, sgcount, dma_length, dev_addr);
328
329 imx_dmav1_writel(dev_addr, DMA_SAR(channel));
330 imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel));
331 } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
332 pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
333 "dev_addr=0x%08x for write\n",
334 channel, __func__, sg, sgcount, dma_length, dev_addr);
335
336 imx_dmav1_writel(dev_addr, DMA_DAR(channel));
337 imx_dmav1_writel(imxdma->ccr_to_device, DMA_CCR(channel));
338 } else {
339 printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n",
340 channel);
341 return -EINVAL;
342 }
343
344 imx_dma_sg_next(channel, sg);
345
346 return 0;
347}
348EXPORT_SYMBOL(imx_dma_setup_sg);
349
350int
351imx_dma_config_channel(int channel, unsigned int config_port,
352 unsigned int config_mem, unsigned int dmareq, int hw_chaining)
353{
354 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
355 u32 dreq = 0;
356
357 imxdma->hw_chaining = 0;
358
359 if (hw_chaining) {
360 imxdma->hw_chaining = 1;
361 if (!imx_dma_hw_chain(imxdma))
362 return -EINVAL;
363 }
364
365 if (dmareq)
366 dreq = CCR_REN;
367
368 imxdma->ccr_from_device = config_port | (config_mem << 2) | dreq;
369 imxdma->ccr_to_device = config_mem | (config_port << 2) | dreq;
370
371 imx_dmav1_writel(dmareq, DMA_RSSR(channel));
372
373 return 0;
374}
375EXPORT_SYMBOL(imx_dma_config_channel);
376
377void imx_dma_config_burstlen(int channel, unsigned int burstlen)
378{
379 imx_dmav1_writel(burstlen, DMA_BLR(channel));
380}
381EXPORT_SYMBOL(imx_dma_config_burstlen);
382
383/**
384 * imx_dma_setup_handlers - setup i.MX DMA channel end and error notification
385 * handlers
386 * @channel: i.MX DMA channel number
387 * @irq_handler: the pointer to the function called if the transfer
388 * ends successfully
389 * @err_handler: the pointer to the function called if the premature
390 * end caused by error occurs
391 * @data: user specified value to be passed to the handlers
392 */
393int
394imx_dma_setup_handlers(int channel,
395 void (*irq_handler) (int, void *),
396 void (*err_handler) (int, void *, int),
397 void *data)
398{
399 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
400 unsigned long flags;
401
402 if (!imxdma->name) {
403 printk(KERN_CRIT "%s: called for not allocated channel %d\n",
404 __func__, channel);
405 return -ENODEV;
406 }
407
408 local_irq_save(flags);
409 imx_dmav1_writel(1 << channel, DMA_DISR);
410 imxdma->irq_handler = irq_handler;
411 imxdma->err_handler = err_handler;
412 imxdma->data = data;
413 local_irq_restore(flags);
414 return 0;
415}
416EXPORT_SYMBOL(imx_dma_setup_handlers);
417
418/**
419 * imx_dma_setup_progression_handler - setup i.MX DMA channel progression
420 * handlers
421 * @channel: i.MX DMA channel number
422 * @prog_handler: the pointer to the function called if the transfer progresses
423 */
424int
425imx_dma_setup_progression_handler(int channel,
426 void (*prog_handler) (int, void*, struct scatterlist*))
427{
428 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
429 unsigned long flags;
430
431 if (!imxdma->name) {
432 printk(KERN_CRIT "%s: called for not allocated channel %d\n",
433 __func__, channel);
434 return -ENODEV;
435 }
436
437 local_irq_save(flags);
438 imxdma->prog_handler = prog_handler;
439 local_irq_restore(flags);
440 return 0;
441}
442EXPORT_SYMBOL(imx_dma_setup_progression_handler);
443
444/**
445 * imx_dma_enable - function to start i.MX DMA channel operation
446 * @channel: i.MX DMA channel number
447 *
448 * The channel has to be allocated by driver through imx_dma_request()
449 * or imx_dma_request_by_prio() function.
450 * The transfer parameters has to be set to the channel registers through
451 * call of the imx_dma_setup_single() or imx_dma_setup_sg() function
452 * and registers %BLR(channel), %RSSR(channel) and %CCR(channel) has to
453 * be set prior this function call by the channel user.
454 */
455void imx_dma_enable(int channel)
456{
457 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
458 unsigned long flags;
459
460 pr_debug("imxdma%d: imx_dma_enable\n", channel);
461
462 if (!imxdma->name) {
463 printk(KERN_CRIT "%s: called for not allocated channel %d\n",
464 __func__, channel);
465 return;
466 }
467
468 if (imxdma->in_use)
469 return;
470
471 local_irq_save(flags);
472
473 imx_dmav1_writel(1 << channel, DMA_DISR);
474 imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) & ~(1 << channel), DMA_DIMR);
475 imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) | CCR_CEN |
476 CCR_ACRPT, DMA_CCR(channel));
477
478#ifdef CONFIG_ARCH_MX2
479 if ((cpu_is_mx21() || cpu_is_mx27()) &&
480 imxdma->sg && imx_dma_hw_chain(imxdma)) {
481 imxdma->sg = sg_next(imxdma->sg);
482 if (imxdma->sg) {
483 u32 tmp;
484 imx_dma_sg_next(channel, imxdma->sg);
485 tmp = imx_dmav1_readl(DMA_CCR(channel));
486 imx_dmav1_writel(tmp | CCR_RPT | CCR_ACRPT,
487 DMA_CCR(channel));
488 }
489 }
490#endif
491 imxdma->in_use = 1;
492
493 local_irq_restore(flags);
494}
495EXPORT_SYMBOL(imx_dma_enable);
496
497/**
498 * imx_dma_disable - stop, finish i.MX DMA channel operatin
499 * @channel: i.MX DMA channel number
500 */
501void imx_dma_disable(int channel)
502{
503 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
504 unsigned long flags;
505
506 pr_debug("imxdma%d: imx_dma_disable\n", channel);
507
508 if (imx_dma_hw_chain(imxdma))
509 del_timer(&imxdma->watchdog);
510
511 local_irq_save(flags);
512 imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) | (1 << channel), DMA_DIMR);
513 imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) & ~CCR_CEN,
514 DMA_CCR(channel));
515 imx_dmav1_writel(1 << channel, DMA_DISR);
516 imxdma->in_use = 0;
517 local_irq_restore(flags);
518}
519EXPORT_SYMBOL(imx_dma_disable);
520
521#ifdef CONFIG_ARCH_MX2
522static void imx_dma_watchdog(unsigned long chno)
523{
524 struct imx_dma_channel *imxdma = &imx_dma_channels[chno];
525
526 imx_dmav1_writel(0, DMA_CCR(chno));
527 imxdma->in_use = 0;
528 imxdma->sg = NULL;
529
530 if (imxdma->err_handler)
531 imxdma->err_handler(chno, imxdma->data, IMX_DMA_ERR_TIMEOUT);
532}
533#endif
534
535static irqreturn_t dma_err_handler(int irq, void *dev_id)
536{
537 int i, disr;
538 struct imx_dma_channel *imxdma;
539 unsigned int err_mask;
540 int errcode;
541
542 disr = imx_dmav1_readl(DMA_DISR);
543
544 err_mask = imx_dmav1_readl(DMA_DBTOSR) |
545 imx_dmav1_readl(DMA_DRTOSR) |
546 imx_dmav1_readl(DMA_DSESR) |
547 imx_dmav1_readl(DMA_DBOSR);
548
549 if (!err_mask)
550 return IRQ_HANDLED;
551
552 imx_dmav1_writel(disr & err_mask, DMA_DISR);
553
554 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
555 if (!(err_mask & (1 << i)))
556 continue;
557 imxdma = &imx_dma_channels[i];
558 errcode = 0;
559
560 if (imx_dmav1_readl(DMA_DBTOSR) & (1 << i)) {
561 imx_dmav1_writel(1 << i, DMA_DBTOSR);
562 errcode |= IMX_DMA_ERR_BURST;
563 }
564 if (imx_dmav1_readl(DMA_DRTOSR) & (1 << i)) {
565 imx_dmav1_writel(1 << i, DMA_DRTOSR);
566 errcode |= IMX_DMA_ERR_REQUEST;
567 }
568 if (imx_dmav1_readl(DMA_DSESR) & (1 << i)) {
569 imx_dmav1_writel(1 << i, DMA_DSESR);
570 errcode |= IMX_DMA_ERR_TRANSFER;
571 }
572 if (imx_dmav1_readl(DMA_DBOSR) & (1 << i)) {
573 imx_dmav1_writel(1 << i, DMA_DBOSR);
574 errcode |= IMX_DMA_ERR_BUFFER;
575 }
576 if (imxdma->name && imxdma->err_handler) {
577 imxdma->err_handler(i, imxdma->data, errcode);
578 continue;
579 }
580
581 imx_dma_channels[i].sg = NULL;
582
583 printk(KERN_WARNING
584 "DMA timeout on channel %d (%s) -%s%s%s%s\n",
585 i, imxdma->name,
586 errcode & IMX_DMA_ERR_BURST ? " burst" : "",
587 errcode & IMX_DMA_ERR_REQUEST ? " request" : "",
588 errcode & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
589 errcode & IMX_DMA_ERR_BUFFER ? " buffer" : "");
590 }
591 return IRQ_HANDLED;
592}
593
594static void dma_irq_handle_channel(int chno)
595{
596 struct imx_dma_channel *imxdma = &imx_dma_channels[chno];
597
598 if (!imxdma->name) {
599 /*
600 * IRQ for an unregistered DMA channel:
601 * let's clear the interrupts and disable it.
602 */
603 printk(KERN_WARNING
604 "spurious IRQ for DMA channel %d\n", chno);
605 return;
606 }
607
608 if (imxdma->sg) {
609 u32 tmp;
610 struct scatterlist *current_sg = imxdma->sg;
611 imxdma->sg = sg_next(imxdma->sg);
612
613 if (imxdma->sg) {
614 imx_dma_sg_next(chno, imxdma->sg);
615
616 tmp = imx_dmav1_readl(DMA_CCR(chno));
617
618 if (imx_dma_hw_chain(imxdma)) {
619 /* FIXME: The timeout should probably be
620 * configurable
621 */
622 mod_timer(&imxdma->watchdog,
623 jiffies + msecs_to_jiffies(500));
624
625 tmp |= CCR_CEN | CCR_RPT | CCR_ACRPT;
626 imx_dmav1_writel(tmp, DMA_CCR(chno));
627 } else {
628 imx_dmav1_writel(tmp & ~CCR_CEN, DMA_CCR(chno));
629 tmp |= CCR_CEN;
630 }
631
632 imx_dmav1_writel(tmp, DMA_CCR(chno));
633
634 if (imxdma->prog_handler)
635 imxdma->prog_handler(chno, imxdma->data,
636 current_sg);
637
638 return;
639 }
640
641 if (imx_dma_hw_chain(imxdma)) {
642 del_timer(&imxdma->watchdog);
643 return;
644 }
645 }
646
647 imx_dmav1_writel(0, DMA_CCR(chno));
648 imxdma->in_use = 0;
649 if (imxdma->irq_handler)
650 imxdma->irq_handler(chno, imxdma->data);
651}
652
653static irqreturn_t dma_irq_handler(int irq, void *dev_id)
654{
655 int i, disr;
656
657#ifdef CONFIG_ARCH_MX2
658 if (cpu_is_mx21() || cpu_is_mx27())
659 dma_err_handler(irq, dev_id);
660#endif
661
662 disr = imx_dmav1_readl(DMA_DISR);
663
664 pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n",
665 disr);
666
667 imx_dmav1_writel(disr, DMA_DISR);
668 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
669 if (disr & (1 << i))
670 dma_irq_handle_channel(i);
671 }
672
673 return IRQ_HANDLED;
674}
675
676/**
677 * imx_dma_request - request/allocate specified channel number
678 * @channel: i.MX DMA channel number
679 * @name: the driver/caller own non-%NULL identification
680 */
681int imx_dma_request(int channel, const char *name)
682{
683 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
684 unsigned long flags;
685 int ret = 0;
686
687 /* basic sanity checks */
688 if (!name)
689 return -EINVAL;
690
691 if (channel >= IMX_DMA_CHANNELS) {
692 printk(KERN_CRIT "%s: called for non-existed channel %d\n",
693 __func__, channel);
694 return -EINVAL;
695 }
696
697 local_irq_save(flags);
698 if (imxdma->name) {
699 local_irq_restore(flags);
700 return -EBUSY;
701 }
702 memset(imxdma, 0, sizeof(imxdma));
703 imxdma->name = name;
704 local_irq_restore(flags); /* request_irq() can block */
705
706#ifdef CONFIG_ARCH_MX2
707 if (cpu_is_mx21() || cpu_is_mx27()) {
708 ret = request_irq(MX2x_INT_DMACH0 + channel,
709 dma_irq_handler, 0, "DMA", NULL);
710 if (ret) {
711 imxdma->name = NULL;
712 pr_crit("Can't register IRQ %d for DMA channel %d\n",
713 MX2x_INT_DMACH0 + channel, channel);
714 return ret;
715 }
716 init_timer(&imxdma->watchdog);
717 imxdma->watchdog.function = &imx_dma_watchdog;
718 imxdma->watchdog.data = channel;
719 }
720#endif
721
722 return ret;
723}
724EXPORT_SYMBOL(imx_dma_request);
725
726/**
727 * imx_dma_free - release previously acquired channel
728 * @channel: i.MX DMA channel number
729 */
730void imx_dma_free(int channel)
731{
732 unsigned long flags;
733 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
734
735 if (!imxdma->name) {
736 printk(KERN_CRIT
737 "%s: trying to free free channel %d\n",
738 __func__, channel);
739 return;
740 }
741
742 local_irq_save(flags);
743 /* Disable interrupts */
744 imx_dma_disable(channel);
745 imxdma->name = NULL;
746
747#ifdef CONFIG_ARCH_MX2
748 if (cpu_is_mx21() || cpu_is_mx27())
749 free_irq(MX2x_INT_DMACH0 + channel, NULL);
750#endif
751
752 local_irq_restore(flags);
753}
754EXPORT_SYMBOL(imx_dma_free);
755
756/**
757 * imx_dma_request_by_prio - find and request some of free channels best
758 * suiting requested priority
759 * @channel: i.MX DMA channel number
760 * @name: the driver/caller own non-%NULL identification
761 *
762 * This function tries to find a free channel in the specified priority group
763 * if the priority cannot be achieved it tries to look for free channel
764 * in the higher and then even lower priority groups.
765 *
766 * Return value: If there is no free channel to allocate, -%ENODEV is returned.
767 * On successful allocation channel is returned.
768 */
769int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio)
770{
771 int i;
772 int best;
773
774 switch (prio) {
775 case (DMA_PRIO_HIGH):
776 best = 8;
777 break;
778 case (DMA_PRIO_MEDIUM):
779 best = 4;
780 break;
781 case (DMA_PRIO_LOW):
782 default:
783 best = 0;
784 break;
785 }
786
787 for (i = best; i < IMX_DMA_CHANNELS; i++)
788 if (!imx_dma_request(i, name))
789 return i;
790
791 for (i = best - 1; i >= 0; i--)
792 if (!imx_dma_request(i, name))
793 return i;
794
795 printk(KERN_ERR "%s: no free DMA channel found\n", __func__);
796
797 return -ENODEV;
798}
799EXPORT_SYMBOL(imx_dma_request_by_prio);
800
801static int __init imx_dma_init(void)
802{
803 int ret = 0;
804 int i;
805
806#ifdef CONFIG_ARCH_MX1
807 if (cpu_is_mx1())
808 imx_dmav1_baseaddr = MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR);
809 else
810#endif
811#ifdef CONFIG_MACH_MX21
812 if (cpu_is_mx21())
813 imx_dmav1_baseaddr = MX21_IO_ADDRESS(MX21_DMA_BASE_ADDR);
814 else
815#endif
816#ifdef CONFIG_MACH_MX27
817 if (cpu_is_mx27())
818 imx_dmav1_baseaddr = MX27_IO_ADDRESS(MX27_DMA_BASE_ADDR);
819 else
820#endif
821 BUG();
822
823 dma_clk = clk_get(NULL, "dma");
824 clk_enable(dma_clk);
825
826 /* reset DMA module */
827 imx_dmav1_writel(DCR_DRST, DMA_DCR);
828
829#ifdef CONFIG_ARCH_MX1
830 if (cpu_is_mx1()) {
831 ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", NULL);
832 if (ret) {
833 pr_crit("Wow! Can't register IRQ for DMA\n");
834 return ret;
835 }
836
837 ret = request_irq(MX1_DMA_ERR, dma_err_handler, 0, "DMA", NULL);
838 if (ret) {
839 pr_crit("Wow! Can't register ERRIRQ for DMA\n");
840 free_irq(MX1_DMA_INT, NULL);
841 return ret;
842 }
843 }
844#endif
845 /* enable DMA module */
846 imx_dmav1_writel(DCR_DEN, DMA_DCR);
847
848 /* clear all interrupts */
849 imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DISR);
850
851 /* disable interrupts */
852 imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DIMR);
853
854 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
855 imx_dma_channels[i].sg = NULL;
856 imx_dma_channels[i].dma_num = i;
857 }
858
859 return ret;
860}
861
862arch_initcall(imx_dma_init);
diff --git a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
new file mode 100644
index 000000000000..4edc5f439201
--- /dev/null
+++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
@@ -0,0 +1,392 @@
1/*
2 * Copyright (C) 2009-2010 Eric Benard - eric@eukrea.com
3 *
4 * Based on pcm970-baseboard.c which is :
5 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22#include <linux/gpio.h>
23#include <linux/irq.h>
24#include <linux/platform_device.h>
25#include <linux/spi/spi.h>
26#include <linux/spi/ads7846.h>
27#include <linux/backlight.h>
28#include <video/platform_lcd.h>
29#include <linux/input/matrix_keypad.h>
30
31#include <asm/mach/arch.h>
32
33#include <mach/common.h>
34#include <mach/iomux-mx27.h>
35#include <mach/imxfb.h>
36#include <mach/hardware.h>
37#include <mach/mmc.h>
38#include <mach/spi.h>
39#include <mach/ssi.h>
40#include <mach/audmux.h>
41
42#include "devices-imx27.h"
43#include "devices.h"
44
45static int eukrea_mbimx27_pins[] = {
46 /* UART2 */
47 PE3_PF_UART2_CTS,
48 PE4_PF_UART2_RTS,
49 PE6_PF_UART2_TXD,
50 PE7_PF_UART2_RXD,
51 /* UART3 */
52 PE8_PF_UART3_TXD,
53 PE9_PF_UART3_RXD,
54 PE10_PF_UART3_CTS,
55 PE11_PF_UART3_RTS,
56 /* UART4 */
57#if !defined(MACH_EUKREA_CPUIMX27_USEUART4)
58 PB26_AF_UART4_RTS,
59 PB28_AF_UART4_TXD,
60 PB29_AF_UART4_CTS,
61 PB31_AF_UART4_RXD,
62#endif
63 /* SDHC1*/
64 PE18_PF_SD1_D0,
65 PE19_PF_SD1_D1,
66 PE20_PF_SD1_D2,
67 PE21_PF_SD1_D3,
68 PE22_PF_SD1_CMD,
69 PE23_PF_SD1_CLK,
70 /* display */
71 PA5_PF_LSCLK,
72 PA6_PF_LD0,
73 PA7_PF_LD1,
74 PA8_PF_LD2,
75 PA9_PF_LD3,
76 PA10_PF_LD4,
77 PA11_PF_LD5,
78 PA12_PF_LD6,
79 PA13_PF_LD7,
80 PA14_PF_LD8,
81 PA15_PF_LD9,
82 PA16_PF_LD10,
83 PA17_PF_LD11,
84 PA18_PF_LD12,
85 PA19_PF_LD13,
86 PA20_PF_LD14,
87 PA21_PF_LD15,
88 PA22_PF_LD16,
89 PA23_PF_LD17,
90 PA28_PF_HSYNC,
91 PA29_PF_VSYNC,
92 PA30_PF_CONTRAST,
93 PA31_PF_OE_ACD,
94 /* SPI1 */
95 PD29_PF_CSPI1_SCLK,
96 PD30_PF_CSPI1_MISO,
97 PD31_PF_CSPI1_MOSI,
98 /* SSI4 */
99#if defined(CONFIG_SND_SOC_EUKREA_TLV320) \
100 || defined(CONFIG_SND_SOC_EUKREA_TLV320_MODULE)
101 PC16_PF_SSI4_FS,
102 PC17_PF_SSI4_RXD | GPIO_PUEN,
103 PC18_PF_SSI4_TXD | GPIO_PUEN,
104 PC19_PF_SSI4_CLK,
105#endif
106};
107
108static const uint32_t eukrea_mbimx27_keymap[] = {
109 KEY(0, 0, KEY_UP),
110 KEY(0, 1, KEY_DOWN),
111 KEY(1, 0, KEY_RIGHT),
112 KEY(1, 1, KEY_LEFT),
113};
114
115static struct matrix_keymap_data eukrea_mbimx27_keymap_data = {
116 .keymap = eukrea_mbimx27_keymap,
117 .keymap_size = ARRAY_SIZE(eukrea_mbimx27_keymap),
118};
119
120static struct gpio_led gpio_leds[] = {
121 {
122 .name = "led1",
123 .default_trigger = "heartbeat",
124 .active_low = 1,
125 .gpio = GPIO_PORTF | 16,
126 },
127 {
128 .name = "led2",
129 .default_trigger = "none",
130 .active_low = 1,
131 .gpio = GPIO_PORTF | 19,
132 },
133};
134
135static struct gpio_led_platform_data gpio_led_info = {
136 .leds = gpio_leds,
137 .num_leds = ARRAY_SIZE(gpio_leds),
138};
139
140static struct platform_device leds_gpio = {
141 .name = "leds-gpio",
142 .id = -1,
143 .dev = {
144 .platform_data = &gpio_led_info,
145 },
146};
147
148static struct imx_fb_videomode eukrea_mbimx27_modes[] = {
149 {
150 .mode = {
151 .name = "CMO-QVGA",
152 .refresh = 60,
153 .xres = 320,
154 .yres = 240,
155 .pixclock = 156000,
156 .hsync_len = 30,
157 .left_margin = 38,
158 .right_margin = 20,
159 .vsync_len = 3,
160 .upper_margin = 15,
161 .lower_margin = 4,
162 },
163 .pcr = 0xFAD08B80,
164 .bpp = 16,
165 }, {
166 .mode = {
167 .name = "DVI-VGA",
168 .refresh = 60,
169 .xres = 640,
170 .yres = 480,
171 .pixclock = 32000,
172 .hsync_len = 1,
173 .left_margin = 35,
174 .right_margin = 0,
175 .vsync_len = 1,
176 .upper_margin = 7,
177 .lower_margin = 0,
178 },
179 .pcr = 0xFA208B80,
180 .bpp = 16,
181 }, {
182 .mode = {
183 .name = "DVI-SVGA",
184 .refresh = 60,
185 .xres = 800,
186 .yres = 600,
187 .pixclock = 25000,
188 .hsync_len = 1,
189 .left_margin = 35,
190 .right_margin = 0,
191 .vsync_len = 1,
192 .upper_margin = 7,
193 .lower_margin = 0,
194 },
195 .pcr = 0xFA208B80,
196 .bpp = 16,
197 },
198};
199
200static struct imx_fb_platform_data eukrea_mbimx27_fb_data = {
201 .mode = eukrea_mbimx27_modes,
202 .num_modes = ARRAY_SIZE(eukrea_mbimx27_modes),
203
204 .pwmr = 0x00A903FF,
205 .lscr1 = 0x00120300,
206 .dmacr = 0x00040060,
207};
208
209static void eukrea_mbimx27_bl_set_intensity(int intensity)
210{
211 if (intensity)
212 gpio_direction_output(GPIO_PORTE | 5, 1);
213 else
214 gpio_direction_output(GPIO_PORTE | 5, 0);
215}
216
217static struct generic_bl_info eukrea_mbimx27_bl_info = {
218 .name = "eukrea_mbimx27-bl",
219 .max_intensity = 0xff,
220 .default_intensity = 0xff,
221 .set_bl_intensity = eukrea_mbimx27_bl_set_intensity,
222};
223
224static struct platform_device eukrea_mbimx27_bl_dev = {
225 .name = "generic-bl",
226 .id = 1,
227 .dev = {
228 .platform_data = &eukrea_mbimx27_bl_info,
229 },
230};
231
232static void eukrea_mbimx27_lcd_power_set(struct plat_lcd_data *pd,
233 unsigned int power)
234{
235 if (power)
236 gpio_direction_output(GPIO_PORTA | 25, 1);
237 else
238 gpio_direction_output(GPIO_PORTA | 25, 0);
239}
240
241static struct plat_lcd_data eukrea_mbimx27_lcd_power_data = {
242 .set_power = eukrea_mbimx27_lcd_power_set,
243};
244
245static struct platform_device eukrea_mbimx27_lcd_powerdev = {
246 .name = "platform-lcd",
247 .dev.platform_data = &eukrea_mbimx27_lcd_power_data,
248};
249
250static const struct imxuart_platform_data uart_pdata __initconst = {
251 .flags = IMXUART_HAVE_RTSCTS,
252};
253
254#if defined(CONFIG_TOUCHSCREEN_ADS7846) \
255 || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
256
257#define ADS7846_PENDOWN (GPIO_PORTD | 25)
258
259static void ads7846_dev_init(void)
260{
261 if (gpio_request(ADS7846_PENDOWN, "ADS7846 pendown") < 0) {
262 printk(KERN_ERR "can't get ads746 pen down GPIO\n");
263 return;
264 }
265 gpio_direction_input(ADS7846_PENDOWN);
266}
267
268static int ads7846_get_pendown_state(void)
269{
270 return !gpio_get_value(ADS7846_PENDOWN);
271}
272
273static struct ads7846_platform_data ads7846_config __initdata = {
274 .get_pendown_state = ads7846_get_pendown_state,
275 .keep_vref_on = 1,
276};
277#endif
278
279#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
280static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = {
281 [0] = {
282 .modalias = "ads7846",
283 .bus_num = 0,
284 .chip_select = 0,
285 .max_speed_hz = 1500000,
286 .irq = IRQ_GPIOD(25),
287 .platform_data = &ads7846_config,
288 .mode = SPI_MODE_2,
289 },
290};
291
292static int eukrea_mbimx27_spi_cs[] = {GPIO_PORTD | 28};
293
294static const struct spi_imx_master eukrea_mbimx27_spi0_data __initconst = {
295 .chipselect = eukrea_mbimx27_spi_cs,
296 .num_chipselect = ARRAY_SIZE(eukrea_mbimx27_spi_cs),
297};
298#endif
299
300static struct i2c_board_info eukrea_mbimx27_i2c_devices[] = {
301 {
302 I2C_BOARD_INFO("tlv320aic23", 0x1a),
303 },
304};
305
306static struct platform_device *platform_devices[] __initdata = {
307 &leds_gpio,
308};
309
310static struct imxmmc_platform_data sdhc_pdata = {
311 .dat3_card_detect = 1,
312};
313
314struct imx_ssi_platform_data eukrea_mbimx27_ssi_pdata = {
315 .flags = IMX_SSI_DMA | IMX_SSI_USE_I2S_SLAVE,
316};
317
318/*
319 * system init for baseboard usage. Will be called by cpuimx27 init.
320 *
321 * Add platform devices present on this baseboard and init
322 * them from CPU side as far as required to use them later on
323 */
324void __init eukrea_mbimx27_baseboard_init(void)
325{
326 mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins,
327 ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27");
328
329#if defined(CONFIG_SND_SOC_EUKREA_TLV320) \
330 || defined(CONFIG_SND_SOC_EUKREA_TLV320_MODULE)
331 /* SSI unit master I2S codec connected to SSI_PINS_4*/
332 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
333 MXC_AUDMUX_V1_PCR_SYN |
334 MXC_AUDMUX_V1_PCR_TFSDIR |
335 MXC_AUDMUX_V1_PCR_TCLKDIR |
336 MXC_AUDMUX_V1_PCR_RFSDIR |
337 MXC_AUDMUX_V1_PCR_RCLKDIR |
338 MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
339 MXC_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
340 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
341 );
342 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
343 MXC_AUDMUX_V1_PCR_SYN |
344 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
345 );
346#endif
347
348 imx27_add_imx_uart1(&uart_pdata);
349 imx27_add_imx_uart2(&uart_pdata);
350#if !defined(MACH_EUKREA_CPUIMX27_USEUART4)
351 imx27_add_imx_uart3(&uart_pdata);
352#endif
353
354 mxc_register_device(&mxc_fb_device, &eukrea_mbimx27_fb_data);
355 mxc_register_device(&mxc_sdhc_device0, &sdhc_pdata);
356
357 i2c_register_board_info(0, eukrea_mbimx27_i2c_devices,
358 ARRAY_SIZE(eukrea_mbimx27_i2c_devices));
359
360 mxc_register_device(&imx_ssi_device0, &eukrea_mbimx27_ssi_pdata);
361
362#if defined(CONFIG_TOUCHSCREEN_ADS7846) \
363 || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
364 /* ADS7846 Touchscreen controller init */
365 mxc_gpio_mode(GPIO_PORTD | 25 | GPIO_GPIO | GPIO_IN);
366 ads7846_dev_init();
367#endif
368
369#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
370 /* SPI_CS0 init */
371 mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
372 imx27_add_spi_imx0(&eukrea_mbimx27_spi0_data);
373 spi_register_board_info(eukrea_mbimx27_spi_board_info,
374 ARRAY_SIZE(eukrea_mbimx27_spi_board_info));
375#endif
376
377 /* Leds configuration */
378 mxc_gpio_mode(GPIO_PORTF | 16 | GPIO_GPIO | GPIO_OUT);
379 mxc_gpio_mode(GPIO_PORTF | 19 | GPIO_GPIO | GPIO_OUT);
380 /* Backlight */
381 mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_OUT);
382 gpio_request(GPIO_PORTE | 5, "backlight");
383 platform_device_register(&eukrea_mbimx27_bl_dev);
384 /* LCD Reset */
385 mxc_gpio_mode(GPIO_PORTA | 25 | GPIO_GPIO | GPIO_OUT);
386 gpio_request(GPIO_PORTA | 25, "lcd_enable");
387 platform_device_register(&eukrea_mbimx27_lcd_powerdev);
388
389 mxc_register_device(&imx_kpp_device, &eukrea_mbimx27_keymap_data);
390
391 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
392}
diff --git a/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h b/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h
new file mode 100644
index 000000000000..df5f522da6b3
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h
@@ -0,0 +1,10 @@
1#ifndef __MACH_DMA_MX1_MX2_H__
2#define __MACH_DMA_MX1_MX2_H__
3/*
4 * Don't use this header in new code, it will go away when all users are
5 * converted to mach/dma-v1.h
6 */
7
8#include <mach/dma-v1.h>
9
10#endif /* ifndef __MACH_DMA_MX1_MX2_H__ */
diff --git a/arch/arm/mach-imx/include/mach/dma-v1.h b/arch/arm/mach-imx/include/mach/dma-v1.h
new file mode 100644
index 000000000000..287431cc13e5
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/dma-v1.h
@@ -0,0 +1,107 @@
1/*
2 * linux/arch/arm/mach-imx/include/mach/dma-v1.h
3 *
4 * i.MX DMA registration and IRQ dispatching
5 *
6 * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz>
7 * Copyright 2008 Juergen Beisert, <kernel@pengutronix.de>
8 * Copyright 2008 Sascha Hauer, <s.hauer@pengutronix.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 * MA 02110-1301, USA.
23 */
24
25#ifndef __MACH_DMA_V1_H__
26#define __MACH_DMA_V1_H__
27
28#define imx_has_dma_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
29
30#define IMX_DMA_CHANNELS 16
31
32#define DMA_MODE_READ 0
33#define DMA_MODE_WRITE 1
34#define DMA_MODE_MASK 1
35
36#define MX1_DMA_REG(offset) MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR + (offset))
37
38/* DMA Interrupt Mask Register */
39#define MX1_DMA_DIMR MX1_DMA_REG(0x08)
40
41/* Channel Control Register */
42#define MX1_DMA_CCR(x) MX1_DMA_REG(0x8c + ((x) << 6))
43
44#define IMX_DMA_MEMSIZE_32 (0 << 4)
45#define IMX_DMA_MEMSIZE_8 (1 << 4)
46#define IMX_DMA_MEMSIZE_16 (2 << 4)
47#define IMX_DMA_TYPE_LINEAR (0 << 10)
48#define IMX_DMA_TYPE_2D (1 << 10)
49#define IMX_DMA_TYPE_FIFO (2 << 10)
50
51#define IMX_DMA_ERR_BURST (1 << 0)
52#define IMX_DMA_ERR_REQUEST (1 << 1)
53#define IMX_DMA_ERR_TRANSFER (1 << 2)
54#define IMX_DMA_ERR_BUFFER (1 << 3)
55#define IMX_DMA_ERR_TIMEOUT (1 << 4)
56
57int
58imx_dma_config_channel(int channel, unsigned int config_port,
59 unsigned int config_mem, unsigned int dmareq, int hw_chaining);
60
61void
62imx_dma_config_burstlen(int channel, unsigned int burstlen);
63
64int
65imx_dma_setup_single(int channel, dma_addr_t dma_address,
66 unsigned int dma_length, unsigned int dev_addr,
67 unsigned int dmamode);
68
69
70/*
71 * Use this flag as the dma_length argument to imx_dma_setup_sg()
72 * to create an endless running dma loop. The end of the scatterlist
73 * must be linked to the beginning for this to work.
74 */
75#define IMX_DMA_LENGTH_LOOP ((unsigned int)-1)
76
77int
78imx_dma_setup_sg(int channel, struct scatterlist *sg,
79 unsigned int sgcount, unsigned int dma_length,
80 unsigned int dev_addr, unsigned int dmamode);
81
82int
83imx_dma_setup_handlers(int channel,
84 void (*irq_handler) (int, void *),
85 void (*err_handler) (int, void *, int), void *data);
86
87int
88imx_dma_setup_progression_handler(int channel,
89 void (*prog_handler) (int, void*, struct scatterlist*));
90
91void imx_dma_enable(int channel);
92
93void imx_dma_disable(int channel);
94
95int imx_dma_request(int channel, const char *name);
96
97void imx_dma_free(int channel);
98
99enum imx_dma_prio {
100 DMA_PRIO_HIGH = 0,
101 DMA_PRIO_MEDIUM = 1,
102 DMA_PRIO_LOW = 2
103};
104
105int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio);
106
107#endif /* __MACH_DMA_V1_H__ */
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c
new file mode 100644
index 000000000000..575ff1ae85a7
--- /dev/null
+++ b/arch/arm/mach-imx/mach-cpuimx27.c
@@ -0,0 +1,317 @@
1/*
2 * Copyright (C) 2009 Eric Benard - eric@eukrea.com
3 *
4 * Based on pcm038.c which is :
5 * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
6 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301, USA.
21 */
22
23#include <linux/i2c.h>
24#include <linux/io.h>
25#include <linux/mtd/plat-ram.h>
26#include <linux/mtd/physmap.h>
27#include <linux/platform_device.h>
28#include <linux/serial_8250.h>
29#include <linux/usb/otg.h>
30#include <linux/usb/ulpi.h>
31#include <linux/fsl_devices.h>
32
33#include <asm/mach-types.h>
34#include <asm/mach/arch.h>
35#include <asm/mach/time.h>
36#include <asm/mach/map.h>
37
38#include <mach/eukrea-baseboards.h>
39#include <mach/common.h>
40#include <mach/hardware.h>
41#include <mach/iomux-mx27.h>
42#include <mach/mxc_nand.h>
43#include <mach/mxc_ehci.h>
44#include <mach/ulpi.h>
45
46#include "devices-imx27.h"
47#include "devices.h"
48
49static int eukrea_cpuimx27_pins[] = {
50 /* UART1 */
51 PE12_PF_UART1_TXD,
52 PE13_PF_UART1_RXD,
53 PE14_PF_UART1_CTS,
54 PE15_PF_UART1_RTS,
55 /* UART4 */
56#if defined(MACH_EUKREA_CPUIMX27_USEUART4)
57 PB26_AF_UART4_RTS,
58 PB28_AF_UART4_TXD,
59 PB29_AF_UART4_CTS,
60 PB31_AF_UART4_RXD,
61#endif
62 /* FEC */
63 PD0_AIN_FEC_TXD0,
64 PD1_AIN_FEC_TXD1,
65 PD2_AIN_FEC_TXD2,
66 PD3_AIN_FEC_TXD3,
67 PD4_AOUT_FEC_RX_ER,
68 PD5_AOUT_FEC_RXD1,
69 PD6_AOUT_FEC_RXD2,
70 PD7_AOUT_FEC_RXD3,
71 PD8_AF_FEC_MDIO,
72 PD9_AIN_FEC_MDC,
73 PD10_AOUT_FEC_CRS,
74 PD11_AOUT_FEC_TX_CLK,
75 PD12_AOUT_FEC_RXD0,
76 PD13_AOUT_FEC_RX_DV,
77 PD14_AOUT_FEC_RX_CLK,
78 PD15_AOUT_FEC_COL,
79 PD16_AIN_FEC_TX_ER,
80 PF23_AIN_FEC_TX_EN,
81 /* I2C1 */
82 PD17_PF_I2C_DATA,
83 PD18_PF_I2C_CLK,
84 /* SDHC2 */
85#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
86 PB4_PF_SD2_D0,
87 PB5_PF_SD2_D1,
88 PB6_PF_SD2_D2,
89 PB7_PF_SD2_D3,
90 PB8_PF_SD2_CMD,
91 PB9_PF_SD2_CLK,
92#endif
93#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
94 /* Quad UART's IRQ */
95 GPIO_PORTB | 22 | GPIO_GPIO | GPIO_IN,
96 GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN,
97 GPIO_PORTB | 27 | GPIO_GPIO | GPIO_IN,
98 GPIO_PORTB | 30 | GPIO_GPIO | GPIO_IN,
99#endif
100 /* OTG */
101 PC7_PF_USBOTG_DATA5,
102 PC8_PF_USBOTG_DATA6,
103 PC9_PF_USBOTG_DATA0,
104 PC10_PF_USBOTG_DATA2,
105 PC11_PF_USBOTG_DATA1,
106 PC12_PF_USBOTG_DATA4,
107 PC13_PF_USBOTG_DATA3,
108 PE0_PF_USBOTG_NXT,
109 PE1_PF_USBOTG_STP,
110 PE2_PF_USBOTG_DIR,
111 PE24_PF_USBOTG_CLK,
112 PE25_PF_USBOTG_DATA7,
113 /* USBH2 */
114 PA0_PF_USBH2_CLK,
115 PA1_PF_USBH2_DIR,
116 PA2_PF_USBH2_DATA7,
117 PA3_PF_USBH2_NXT,
118 PA4_PF_USBH2_STP,
119 PD19_AF_USBH2_DATA4,
120 PD20_AF_USBH2_DATA3,
121 PD21_AF_USBH2_DATA6,
122 PD22_AF_USBH2_DATA0,
123 PD23_AF_USBH2_DATA2,
124 PD24_AF_USBH2_DATA1,
125 PD26_AF_USBH2_DATA5,
126};
127
128static struct physmap_flash_data eukrea_cpuimx27_flash_data = {
129 .width = 2,
130};
131
132static struct resource eukrea_cpuimx27_flash_resource = {
133 .start = 0xc0000000,
134 .end = 0xc3ffffff,
135 .flags = IORESOURCE_MEM,
136};
137
138static struct platform_device eukrea_cpuimx27_nor_mtd_device = {
139 .name = "physmap-flash",
140 .id = 0,
141 .dev = {
142 .platform_data = &eukrea_cpuimx27_flash_data,
143 },
144 .num_resources = 1,
145 .resource = &eukrea_cpuimx27_flash_resource,
146};
147
148static const struct imxuart_platform_data uart_pdata __initconst = {
149 .flags = IMXUART_HAVE_RTSCTS,
150};
151
152static const struct mxc_nand_platform_data
153cpuimx27_nand_board_info __initconst = {
154 .width = 1,
155 .hw_ecc = 1,
156};
157
158static struct platform_device *platform_devices[] __initdata = {
159 &eukrea_cpuimx27_nor_mtd_device,
160 &mxc_fec_device,
161 &mxc_wdt,
162 &mxc_w1_master_device,
163};
164
165static const struct imxi2c_platform_data cpuimx27_i2c1_data __initconst = {
166 .bitrate = 100000,
167};
168
169static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = {
170 {
171 I2C_BOARD_INFO("pcf8563", 0x51),
172 },
173};
174
175#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
176static struct plat_serial8250_port serial_platform_data[] = {
177 {
178 .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x200000),
179 .irq = IRQ_GPIOB(23),
180 .uartclk = 14745600,
181 .regshift = 1,
182 .iotype = UPIO_MEM,
183 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
184 }, {
185 .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x400000),
186 .irq = IRQ_GPIOB(22),
187 .uartclk = 14745600,
188 .regshift = 1,
189 .iotype = UPIO_MEM,
190 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
191 }, {
192 .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x800000),
193 .irq = IRQ_GPIOB(27),
194 .uartclk = 14745600,
195 .regshift = 1,
196 .iotype = UPIO_MEM,
197 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
198 }, {
199 .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x1000000),
200 .irq = IRQ_GPIOB(30),
201 .uartclk = 14745600,
202 .regshift = 1,
203 .iotype = UPIO_MEM,
204 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
205 }, {
206 }
207};
208
209static struct platform_device serial_device = {
210 .name = "serial8250",
211 .id = 0,
212 .dev = {
213 .platform_data = serial_platform_data,
214 },
215};
216#endif
217
218#if defined(CONFIG_USB_ULPI)
219static struct mxc_usbh_platform_data otg_pdata = {
220 .portsc = MXC_EHCI_MODE_ULPI,
221 .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
222};
223
224static struct mxc_usbh_platform_data usbh2_pdata = {
225 .portsc = MXC_EHCI_MODE_ULPI,
226 .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
227};
228#endif
229
230static struct fsl_usb2_platform_data otg_device_pdata = {
231 .operating_mode = FSL_USB2_DR_DEVICE,
232 .phy_mode = FSL_USB2_PHY_ULPI,
233};
234
235static int otg_mode_host;
236
237static int __init eukrea_cpuimx27_otg_mode(char *options)
238{
239 if (!strcmp(options, "host"))
240 otg_mode_host = 1;
241 else if (!strcmp(options, "device"))
242 otg_mode_host = 0;
243 else
244 pr_info("otg_mode neither \"host\" nor \"device\". "
245 "Defaulting to device\n");
246 return 0;
247}
248__setup("otg_mode=", eukrea_cpuimx27_otg_mode);
249
250static void __init eukrea_cpuimx27_init(void)
251{
252 mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins,
253 ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27");
254
255 imx27_add_imx_uart0(&uart_pdata);
256
257 imx27_add_mxc_nand(&cpuimx27_nand_board_info);
258
259 i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices,
260 ARRAY_SIZE(eukrea_cpuimx27_i2c_devices));
261
262 imx27_add_i2c_imx1(&cpuimx27_i2c1_data);
263
264 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
265
266#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
267 /* SDHC2 can be used for Wifi */
268 mxc_register_device(&mxc_sdhc_device1, NULL);
269#endif
270#if defined(MACH_EUKREA_CPUIMX27_USEUART4)
271 /* in which case UART4 is also used for Bluetooth */
272 imx27_add_imx_uart3(&uart_pdata);
273#endif
274
275#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
276 platform_device_register(&serial_device);
277#endif
278
279#if defined(CONFIG_USB_ULPI)
280 if (otg_mode_host) {
281 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
282 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
283
284 mxc_register_device(&mxc_otg_host, &otg_pdata);
285 }
286
287 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
288 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
289
290 mxc_register_device(&mxc_usbh2, &usbh2_pdata);
291#endif
292 if (!otg_mode_host)
293 mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
294
295#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD
296 eukrea_mbimx27_baseboard_init();
297#endif
298}
299
300static void __init eukrea_cpuimx27_timer_init(void)
301{
302 mx27_clocks_init(26000000);
303}
304
305static struct sys_timer eukrea_cpuimx27_timer = {
306 .init = eukrea_cpuimx27_timer_init,
307};
308
309MACHINE_START(CPUIMX27, "EUKREA CPUIMX27")
310 .phys_io = MX27_AIPI_BASE_ADDR,
311 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
312 .boot_params = MX27_PHYS_OFFSET + 0x100,
313 .map_io = mx27_map_io,
314 .init_irq = mx27_init_irq,
315 .init_machine = eukrea_cpuimx27_init,
316 .timer = &eukrea_cpuimx27_timer,
317MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx27lite.c b/arch/arm/mach-imx/mach-imx27lite.c
new file mode 100644
index 000000000000..22a2b5d91213
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx27lite.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
3 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
4 * Copyright 2009 Daniel Schaeffer (daniel.schaeffer@timesys.com)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/platform_device.h>
18#include <linux/gpio.h>
19#include <asm/mach-types.h>
20#include <asm/mach/arch.h>
21#include <asm/mach/time.h>
22#include <asm/mach/map.h>
23#include <mach/hardware.h>
24#include <mach/common.h>
25#include <mach/iomux-mx27.h>
26
27#include "devices-imx27.h"
28#include "devices.h"
29
30static unsigned int mx27lite_pins[] = {
31 /* UART1 */
32 PE12_PF_UART1_TXD,
33 PE13_PF_UART1_RXD,
34 PE14_PF_UART1_CTS,
35 PE15_PF_UART1_RTS,
36 /* FEC */
37 PD0_AIN_FEC_TXD0,
38 PD1_AIN_FEC_TXD1,
39 PD2_AIN_FEC_TXD2,
40 PD3_AIN_FEC_TXD3,
41 PD4_AOUT_FEC_RX_ER,
42 PD5_AOUT_FEC_RXD1,
43 PD6_AOUT_FEC_RXD2,
44 PD7_AOUT_FEC_RXD3,
45 PD8_AF_FEC_MDIO,
46 PD9_AIN_FEC_MDC,
47 PD10_AOUT_FEC_CRS,
48 PD11_AOUT_FEC_TX_CLK,
49 PD12_AOUT_FEC_RXD0,
50 PD13_AOUT_FEC_RX_DV,
51 PD14_AOUT_FEC_RX_CLK,
52 PD15_AOUT_FEC_COL,
53 PD16_AIN_FEC_TX_ER,
54 PF23_AIN_FEC_TX_EN,
55};
56
57static const struct imxuart_platform_data uart_pdata __initconst = {
58 .flags = IMXUART_HAVE_RTSCTS,
59};
60
61static struct platform_device *platform_devices[] __initdata = {
62 &mxc_fec_device,
63};
64
65static void __init mx27lite_init(void)
66{
67 mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
68 "imx27lite");
69 imx27_add_imx_uart0(&uart_pdata);
70 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
71}
72
73static void __init mx27lite_timer_init(void)
74{
75 mx27_clocks_init(26000000);
76}
77
78static struct sys_timer mx27lite_timer = {
79 .init = mx27lite_timer_init,
80};
81
82MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE")
83 .phys_io = MX27_AIPI_BASE_ADDR,
84 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
85 .boot_params = MX27_PHYS_OFFSET + 0x100,
86 .map_io = mx27_map_io,
87 .init_irq = mx27_init_irq,
88 .init_machine = mx27lite_init,
89 .timer = &mx27lite_timer,
90MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx1ads.c b/arch/arm/mach-imx/mach-mx1ads.c
new file mode 100644
index 000000000000..77a760cfadc0
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx1ads.c
@@ -0,0 +1,165 @@
1/*
2 * arch/arm/mach-imx/mach-mx1ads.c
3 *
4 * Initially based on:
5 * linux-2.6.7-imx/arch/arm/mach-imx/scb9328.c
6 * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
7 *
8 * 2004 (c) MontaVista Software, Inc.
9 *
10 * This file is licensed under the terms of the GNU General Public
11 * License version 2. This program is licensed "as is" without any
12 * warranty of any kind, whether express or implied.
13 */
14
15#include <linux/i2c.h>
16#include <linux/i2c/pcf857x.h>
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/platform_device.h>
20#include <linux/mtd/physmap.h>
21
22#include <asm/mach-types.h>
23#include <asm/mach/arch.h>
24#include <asm/mach/time.h>
25
26#include <mach/common.h>
27#include <mach/hardware.h>
28#include <mach/i2c.h>
29#include <mach/iomux-mx1.h>
30#include <mach/irqs.h>
31
32#include "devices-imx1.h"
33#include "devices.h"
34
35static int mx1ads_pins[] = {
36 /* UART1 */
37 PC9_PF_UART1_CTS,
38 PC10_PF_UART1_RTS,
39 PC11_PF_UART1_TXD,
40 PC12_PF_UART1_RXD,
41 /* UART2 */
42 PB28_PF_UART2_CTS,
43 PB29_PF_UART2_RTS,
44 PB30_PF_UART2_TXD,
45 PB31_PF_UART2_RXD,
46 /* I2C */
47 PA15_PF_I2C_SDA,
48 PA16_PF_I2C_SCL,
49 /* SPI */
50 PC13_PF_SPI1_SPI_RDY,
51 PC14_PF_SPI1_SCLK,
52 PC15_PF_SPI1_SS,
53 PC16_PF_SPI1_MISO,
54 PC17_PF_SPI1_MOSI,
55};
56
57/*
58 * UARTs platform data
59 */
60
61static const struct imxuart_platform_data uart0_pdata __initconst = {
62 .flags = IMXUART_HAVE_RTSCTS,
63};
64
65static const struct imxuart_platform_data uart1_pdata __initconst = {
66 .flags = IMXUART_HAVE_RTSCTS,
67};
68
69/*
70 * Physmap flash
71 */
72
73static struct physmap_flash_data mx1ads_flash_data = {
74 .width = 4, /* bankwidth in bytes */
75};
76
77static struct resource flash_resource = {
78 .start = MX1_CS0_PHYS,
79 .end = MX1_CS0_PHYS + SZ_32M - 1,
80 .flags = IORESOURCE_MEM,
81};
82
83static struct platform_device flash_device = {
84 .name = "physmap-flash",
85 .id = 0,
86 .resource = &flash_resource,
87 .num_resources = 1,
88};
89
90/*
91 * I2C
92 */
93static struct pcf857x_platform_data pcf857x_data[] = {
94 {
95 .gpio_base = 4 * 32,
96 }, {
97 .gpio_base = 4 * 32 + 16,
98 }
99};
100
101static const struct imxi2c_platform_data mx1ads_i2c_data __initconst = {
102 .bitrate = 100000,
103};
104
105static struct i2c_board_info mx1ads_i2c_devices[] = {
106 {
107 I2C_BOARD_INFO("pcf8575", 0x22),
108 .platform_data = &pcf857x_data[0],
109 }, {
110 I2C_BOARD_INFO("pcf8575", 0x24),
111 .platform_data = &pcf857x_data[1],
112 },
113};
114
115/*
116 * Board init
117 */
118static void __init mx1ads_init(void)
119{
120 mxc_gpio_setup_multiple_pins(mx1ads_pins,
121 ARRAY_SIZE(mx1ads_pins), "mx1ads");
122
123 /* UART */
124 imx1_add_imx_uart0(&uart0_pdata);
125 imx1_add_imx_uart1(&uart1_pdata);
126
127 /* Physmap flash */
128 mxc_register_device(&flash_device, &mx1ads_flash_data);
129
130 /* I2C */
131 i2c_register_board_info(0, mx1ads_i2c_devices,
132 ARRAY_SIZE(mx1ads_i2c_devices));
133
134 imx1_add_i2c_imx(&mx1ads_i2c_data);
135}
136
137static void __init mx1ads_timer_init(void)
138{
139 mx1_clocks_init(32000);
140}
141
142struct sys_timer mx1ads_timer = {
143 .init = mx1ads_timer_init,
144};
145
146MACHINE_START(MX1ADS, "Freescale MX1ADS")
147 /* Maintainer: Sascha Hauer, Pengutronix */
148 .phys_io = MX1_IO_BASE_ADDR,
149 .io_pg_offst = (MX1_IO_BASE_ADDR_VIRT >> 18) & 0xfffc,
150 .boot_params = MX1_PHYS_OFFSET + 0x100,
151 .map_io = mx1_map_io,
152 .init_irq = mx1_init_irq,
153 .timer = &mx1ads_timer,
154 .init_machine = mx1ads_init,
155MACHINE_END
156
157MACHINE_START(MXLADS, "Freescale MXLADS")
158 .phys_io = MX1_IO_BASE_ADDR,
159 .io_pg_offst = (MX1_IO_BASE_ADDR_VIRT >> 18) & 0xfffc,
160 .boot_params = MX1_PHYS_OFFSET + 0x100,
161 .map_io = mx1_map_io,
162 .init_irq = mx1_init_irq,
163 .timer = &mx1ads_timer,
164 .init_machine = mx1ads_init,
165MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c
new file mode 100644
index 000000000000..96d7f8189f32
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -0,0 +1,324 @@
1/*
2 * Copyright (C) 2000 Deep Blue Solutions Ltd
3 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
4 * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/platform_device.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/physmap.h>
20#include <linux/gpio.h>
21#include <mach/common.h>
22#include <mach/hardware.h>
23#include <asm/mach-types.h>
24#include <asm/mach/arch.h>
25#include <asm/mach/time.h>
26#include <asm/mach/map.h>
27#include <mach/imxfb.h>
28#include <mach/iomux-mx21.h>
29#include <mach/mxc_nand.h>
30#include <mach/mmc.h>
31
32#include "devices-imx21.h"
33#include "devices.h"
34
35/*
36 * Memory-mapped I/O on MX21ADS base board
37 */
38#define MX21ADS_MMIO_BASE_ADDR 0xf5000000
39#define MX21ADS_MMIO_SIZE SZ_16M
40
41#define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \
42 (MX21ADS_MMIO_BASE_ADDR + (offset))
43
44#define MX21ADS_CS8900A_IRQ IRQ_GPIOE(11)
45#define MX21ADS_CS8900A_IOBASE_REG MX21ADS_REG_ADDR(0x000000)
46#define MX21ADS_ST16C255_IOBASE_REG MX21ADS_REG_ADDR(0x200000)
47#define MX21ADS_VERSION_REG MX21ADS_REG_ADDR(0x400000)
48#define MX21ADS_IO_REG MX21ADS_REG_ADDR(0x800000)
49
50/* MX21ADS_IO_REG bit definitions */
51#define MX21ADS_IO_SD_WP 0x0001 /* read */
52#define MX21ADS_IO_TP6 0x0001 /* write */
53#define MX21ADS_IO_SW_SEL 0x0002 /* read */
54#define MX21ADS_IO_TP7 0x0002 /* write */
55#define MX21ADS_IO_RESET_E_UART 0x0004
56#define MX21ADS_IO_RESET_BASE 0x0008
57#define MX21ADS_IO_CSI_CTL2 0x0010
58#define MX21ADS_IO_CSI_CTL1 0x0020
59#define MX21ADS_IO_CSI_CTL0 0x0040
60#define MX21ADS_IO_UART1_EN 0x0080
61#define MX21ADS_IO_UART4_EN 0x0100
62#define MX21ADS_IO_LCDON 0x0200
63#define MX21ADS_IO_IRDA_EN 0x0400
64#define MX21ADS_IO_IRDA_FIR_SEL 0x0800
65#define MX21ADS_IO_IRDA_MD0_B 0x1000
66#define MX21ADS_IO_IRDA_MD1 0x2000
67#define MX21ADS_IO_LED4_ON 0x4000
68#define MX21ADS_IO_LED3_ON 0x8000
69
70static unsigned int mx21ads_pins[] = {
71
72 /* CS8900A */
73 (GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11),
74
75 /* UART1 */
76 PE12_PF_UART1_TXD,
77 PE13_PF_UART1_RXD,
78 PE14_PF_UART1_CTS,
79 PE15_PF_UART1_RTS,
80
81 /* UART3 (IrDA) - only TXD and RXD */
82 PE8_PF_UART3_TXD,
83 PE9_PF_UART3_RXD,
84
85 /* UART4 */
86 PB26_AF_UART4_RTS,
87 PB28_AF_UART4_TXD,
88 PB29_AF_UART4_CTS,
89 PB31_AF_UART4_RXD,
90
91 /* LCDC */
92 PA5_PF_LSCLK,
93 PA6_PF_LD0,
94 PA7_PF_LD1,
95 PA8_PF_LD2,
96 PA9_PF_LD3,
97 PA10_PF_LD4,
98 PA11_PF_LD5,
99 PA12_PF_LD6,
100 PA13_PF_LD7,
101 PA14_PF_LD8,
102 PA15_PF_LD9,
103 PA16_PF_LD10,
104 PA17_PF_LD11,
105 PA18_PF_LD12,
106 PA19_PF_LD13,
107 PA20_PF_LD14,
108 PA21_PF_LD15,
109 PA22_PF_LD16,
110 PA24_PF_REV, /* Sharp panel dedicated signal */
111 PA25_PF_CLS, /* Sharp panel dedicated signal */
112 PA26_PF_PS, /* Sharp panel dedicated signal */
113 PA27_PF_SPL_SPR, /* Sharp panel dedicated signal */
114 PA28_PF_HSYNC,
115 PA29_PF_VSYNC,
116 PA30_PF_CONTRAST,
117 PA31_PF_OE_ACD,
118
119 /* MMC/SDHC */
120 PE18_PF_SD1_D0,
121 PE19_PF_SD1_D1,
122 PE20_PF_SD1_D2,
123 PE21_PF_SD1_D3,
124 PE22_PF_SD1_CMD,
125 PE23_PF_SD1_CLK,
126
127 /* NFC */
128 PF0_PF_NRFB,
129 PF1_PF_NFCE,
130 PF2_PF_NFWP,
131 PF3_PF_NFCLE,
132 PF4_PF_NFALE,
133 PF5_PF_NFRE,
134 PF6_PF_NFWE,
135 PF7_PF_NFIO0,
136 PF8_PF_NFIO1,
137 PF9_PF_NFIO2,
138 PF10_PF_NFIO3,
139 PF11_PF_NFIO4,
140 PF12_PF_NFIO5,
141 PF13_PF_NFIO6,
142 PF14_PF_NFIO7,
143};
144
145/* ADS's NOR flash: 2x AM29BDS128HE9VKI on 32-bit bus */
146static struct physmap_flash_data mx21ads_flash_data = {
147 .width = 4,
148};
149
150static struct resource mx21ads_flash_resource = {
151 .start = MX21_CS0_BASE_ADDR,
152 .end = MX21_CS0_BASE_ADDR + 0x02000000 - 1,
153 .flags = IORESOURCE_MEM,
154};
155
156static struct platform_device mx21ads_nor_mtd_device = {
157 .name = "physmap-flash",
158 .id = 0,
159 .dev = {
160 .platform_data = &mx21ads_flash_data,
161 },
162 .num_resources = 1,
163 .resource = &mx21ads_flash_resource,
164};
165
166static const struct imxuart_platform_data uart_pdata_rts __initconst = {
167 .flags = IMXUART_HAVE_RTSCTS,
168};
169
170static const struct imxuart_platform_data uart_pdata_norts __initconst = {
171};
172
173static int mx21ads_fb_init(struct platform_device *pdev)
174{
175 u16 tmp;
176
177 tmp = __raw_readw(MX21ADS_IO_REG);
178 tmp |= MX21ADS_IO_LCDON;
179 __raw_writew(tmp, MX21ADS_IO_REG);
180 return 0;
181}
182
183static void mx21ads_fb_exit(struct platform_device *pdev)
184{
185 u16 tmp;
186
187 tmp = __raw_readw(MX21ADS_IO_REG);
188 tmp &= ~MX21ADS_IO_LCDON;
189 __raw_writew(tmp, MX21ADS_IO_REG);
190}
191
192/*
193 * Connected is a portrait Sharp-QVGA display
194 * of type: LQ035Q7DB02
195 */
196static struct imx_fb_videomode mx21ads_modes[] = {
197 {
198 .mode = {
199 .name = "Sharp-LQ035Q7",
200 .refresh = 60,
201 .xres = 240,
202 .yres = 320,
203 .pixclock = 188679, /* in ps (5.3MHz) */
204 .hsync_len = 2,
205 .left_margin = 6,
206 .right_margin = 16,
207 .vsync_len = 1,
208 .upper_margin = 8,
209 .lower_margin = 10,
210 },
211 .pcr = 0xfb108bc7,
212 .bpp = 16,
213 },
214};
215
216static struct imx_fb_platform_data mx21ads_fb_data = {
217 .mode = mx21ads_modes,
218 .num_modes = ARRAY_SIZE(mx21ads_modes),
219
220 .pwmr = 0x00a903ff,
221 .lscr1 = 0x00120300,
222 .dmacr = 0x00020008,
223
224 .init = mx21ads_fb_init,
225 .exit = mx21ads_fb_exit,
226};
227
228static int mx21ads_sdhc_get_ro(struct device *dev)
229{
230 return (__raw_readw(MX21ADS_IO_REG) & MX21ADS_IO_SD_WP) ? 1 : 0;
231}
232
233static int mx21ads_sdhc_init(struct device *dev, irq_handler_t detect_irq,
234 void *data)
235{
236 int ret;
237
238 ret = request_irq(IRQ_GPIOD(25), detect_irq,
239 IRQF_TRIGGER_FALLING, "mmc-detect", data);
240 if (ret)
241 goto out;
242 return 0;
243out:
244 return ret;
245}
246
247static void mx21ads_sdhc_exit(struct device *dev, void *data)
248{
249 free_irq(IRQ_GPIOD(25), data);
250}
251
252static struct imxmmc_platform_data mx21ads_sdhc_pdata = {
253 .ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, /* 3.0V */
254 .get_ro = mx21ads_sdhc_get_ro,
255 .init = mx21ads_sdhc_init,
256 .exit = mx21ads_sdhc_exit,
257};
258
259static const struct mxc_nand_platform_data
260mx21ads_nand_board_info __initconst = {
261 .width = 1,
262 .hw_ecc = 1,
263};
264
265static struct map_desc mx21ads_io_desc[] __initdata = {
266 /*
267 * Memory-mapped I/O on MX21ADS Base board:
268 * - CS8900A Ethernet controller
269 * - ST16C2552CJ UART
270 * - CPU and Base board version
271 * - Base board I/O register
272 */
273 {
274 .virtual = MX21ADS_MMIO_BASE_ADDR,
275 .pfn = __phys_to_pfn(MX21_CS1_BASE_ADDR),
276 .length = MX21ADS_MMIO_SIZE,
277 .type = MT_DEVICE,
278 },
279};
280
281static void __init mx21ads_map_io(void)
282{
283 mx21_map_io();
284 iotable_init(mx21ads_io_desc, ARRAY_SIZE(mx21ads_io_desc));
285}
286
287static struct platform_device *platform_devices[] __initdata = {
288 &mx21ads_nor_mtd_device,
289};
290
291static void __init mx21ads_board_init(void)
292{
293 mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins),
294 "mx21ads");
295
296 imx21_add_imx_uart0(&uart_pdata_rts);
297 imx21_add_imx_uart2(&uart_pdata_norts);
298 imx21_add_imx_uart3(&uart_pdata_rts);
299 mxc_register_device(&mxc_fb_device, &mx21ads_fb_data);
300 mxc_register_device(&mxc_sdhc_device0, &mx21ads_sdhc_pdata);
301 imx21_add_mxc_nand(&mx21ads_nand_board_info);
302
303 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
304}
305
306static void __init mx21ads_timer_init(void)
307{
308 mx21_clocks_init(32768, 26000000);
309}
310
311static struct sys_timer mx21ads_timer = {
312 .init = mx21ads_timer_init,
313};
314
315MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
316 /* maintainer: Freescale Semiconductor, Inc. */
317 .phys_io = MX21_AIPI_BASE_ADDR,
318 .io_pg_offst = ((MX21_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
319 .boot_params = MX21_PHYS_OFFSET + 0x100,
320 .map_io = mx21ads_map_io,
321 .init_irq = mx21_init_irq,
322 .init_machine = mx21ads_board_init,
323 .timer = &mx21ads_timer,
324MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
new file mode 100644
index 000000000000..e66ffaa1c26c
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -0,0 +1,119 @@
1/*
2 * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * Author: Fabio Estevam <fabio.estevam@freescale.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17/*
18 * This machine is known as:
19 * - i.MX27 3-Stack Development System
20 * - i.MX27 Platform Development Kit (i.MX27 PDK)
21 */
22
23#include <linux/platform_device.h>
24#include <linux/gpio.h>
25#include <linux/input/matrix_keypad.h>
26#include <asm/mach-types.h>
27#include <asm/mach/arch.h>
28#include <asm/mach/time.h>
29#include <mach/hardware.h>
30#include <mach/common.h>
31#include <mach/iomux-mx27.h>
32
33#include "devices-imx27.h"
34#include "devices.h"
35
36static unsigned int mx27pdk_pins[] = {
37 /* UART1 */
38 PE12_PF_UART1_TXD,
39 PE13_PF_UART1_RXD,
40 PE14_PF_UART1_CTS,
41 PE15_PF_UART1_RTS,
42 /* FEC */
43 PD0_AIN_FEC_TXD0,
44 PD1_AIN_FEC_TXD1,
45 PD2_AIN_FEC_TXD2,
46 PD3_AIN_FEC_TXD3,
47 PD4_AOUT_FEC_RX_ER,
48 PD5_AOUT_FEC_RXD1,
49 PD6_AOUT_FEC_RXD2,
50 PD7_AOUT_FEC_RXD3,
51 PD8_AF_FEC_MDIO,
52 PD9_AIN_FEC_MDC,
53 PD10_AOUT_FEC_CRS,
54 PD11_AOUT_FEC_TX_CLK,
55 PD12_AOUT_FEC_RXD0,
56 PD13_AOUT_FEC_RX_DV,
57 PD14_AOUT_FEC_RX_CLK,
58 PD15_AOUT_FEC_COL,
59 PD16_AIN_FEC_TX_ER,
60 PF23_AIN_FEC_TX_EN,
61};
62
63static const struct imxuart_platform_data uart_pdata __initconst = {
64 .flags = IMXUART_HAVE_RTSCTS,
65};
66
67static struct platform_device *platform_devices[] __initdata = {
68 &mxc_fec_device,
69};
70
71/*
72 * Matrix keyboard
73 */
74
75static const uint32_t mx27_3ds_keymap[] = {
76 KEY(0, 0, KEY_UP),
77 KEY(0, 1, KEY_DOWN),
78 KEY(1, 0, KEY_RIGHT),
79 KEY(1, 1, KEY_LEFT),
80 KEY(1, 2, KEY_ENTER),
81 KEY(2, 0, KEY_F6),
82 KEY(2, 1, KEY_F8),
83 KEY(2, 2, KEY_F9),
84 KEY(2, 3, KEY_F10),
85};
86
87static struct matrix_keymap_data mx27_3ds_keymap_data = {
88 .keymap = mx27_3ds_keymap,
89 .keymap_size = ARRAY_SIZE(mx27_3ds_keymap),
90};
91
92static void __init mx27pdk_init(void)
93{
94 mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
95 "mx27pdk");
96 imx27_add_imx_uart0(&uart_pdata);
97 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
98 mxc_register_device(&imx_kpp_device, &mx27_3ds_keymap_data);
99}
100
101static void __init mx27pdk_timer_init(void)
102{
103 mx27_clocks_init(26000000);
104}
105
106static struct sys_timer mx27pdk_timer = {
107 .init = mx27pdk_timer_init,
108};
109
110MACHINE_START(MX27_3DS, "Freescale MX27PDK")
111 /* maintainer: Freescale Semiconductor, Inc. */
112 .phys_io = MX27_AIPI_BASE_ADDR,
113 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
114 .boot_params = MX27_PHYS_OFFSET + 0x100,
115 .map_io = mx27_map_io,
116 .init_irq = mx27_init_irq,
117 .init_machine = mx27pdk_init,
118 .timer = &mx27pdk_timer,
119MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c
new file mode 100644
index 000000000000..9c77da98a10e
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx27ads.c
@@ -0,0 +1,357 @@
1/*
2 * Copyright (C) 2000 Deep Blue Solutions Ltd
3 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
4 * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/platform_device.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/map.h>
20#include <linux/mtd/partitions.h>
21#include <linux/mtd/physmap.h>
22#include <linux/i2c.h>
23#include <linux/irq.h>
24#include <mach/common.h>
25#include <mach/hardware.h>
26#include <asm/mach-types.h>
27#include <asm/mach/arch.h>
28#include <asm/mach/time.h>
29#include <asm/mach/map.h>
30#include <mach/gpio.h>
31#include <mach/iomux-mx27.h>
32#include <mach/mxc_nand.h>
33#include <mach/imxfb.h>
34#include <mach/mmc.h>
35
36#include "devices-imx27.h"
37#include "devices.h"
38
39/*
40 * Base address of PBC controller, CS4
41 */
42#define PBC_BASE_ADDRESS 0xf4300000
43#define PBC_REG_ADDR(offset) (void __force __iomem *) \
44 (PBC_BASE_ADDRESS + (offset))
45
46/* When the PBC address connection is fixed in h/w, defined as 1 */
47#define PBC_ADDR_SH 0
48
49/* Offsets for the PBC Controller register */
50/*
51 * PBC Board version register offset
52 */
53#define PBC_VERSION_REG PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH)
54/*
55 * PBC Board control register 1 set address.
56 */
57#define PBC_BCTRL1_SET_REG PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH)
58/*
59 * PBC Board control register 1 clear address.
60 */
61#define PBC_BCTRL1_CLEAR_REG PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH)
62
63/* PBC Board Control Register 1 bit definitions */
64#define PBC_BCTRL1_LCDON 0x0800 /* Enable the LCD */
65
66/* to determine the correct external crystal reference */
67#define CKIH_27MHZ_BIT_SET (1 << 3)
68
69static unsigned int mx27ads_pins[] = {
70 /* UART0 */
71 PE12_PF_UART1_TXD,
72 PE13_PF_UART1_RXD,
73 PE14_PF_UART1_CTS,
74 PE15_PF_UART1_RTS,
75 /* UART1 */
76 PE3_PF_UART2_CTS,
77 PE4_PF_UART2_RTS,
78 PE6_PF_UART2_TXD,
79 PE7_PF_UART2_RXD,
80 /* UART2 */
81 PE8_PF_UART3_TXD,
82 PE9_PF_UART3_RXD,
83 PE10_PF_UART3_CTS,
84 PE11_PF_UART3_RTS,
85 /* UART3 */
86 PB26_AF_UART4_RTS,
87 PB28_AF_UART4_TXD,
88 PB29_AF_UART4_CTS,
89 PB31_AF_UART4_RXD,
90 /* UART4 */
91 PB18_AF_UART5_TXD,
92 PB19_AF_UART5_RXD,
93 PB20_AF_UART5_CTS,
94 PB21_AF_UART5_RTS,
95 /* UART5 */
96 PB10_AF_UART6_TXD,
97 PB12_AF_UART6_CTS,
98 PB11_AF_UART6_RXD,
99 PB13_AF_UART6_RTS,
100 /* FEC */
101 PD0_AIN_FEC_TXD0,
102 PD1_AIN_FEC_TXD1,
103 PD2_AIN_FEC_TXD2,
104 PD3_AIN_FEC_TXD3,
105 PD4_AOUT_FEC_RX_ER,
106 PD5_AOUT_FEC_RXD1,
107 PD6_AOUT_FEC_RXD2,
108 PD7_AOUT_FEC_RXD3,
109 PD8_AF_FEC_MDIO,
110 PD9_AIN_FEC_MDC,
111 PD10_AOUT_FEC_CRS,
112 PD11_AOUT_FEC_TX_CLK,
113 PD12_AOUT_FEC_RXD0,
114 PD13_AOUT_FEC_RX_DV,
115 PD14_AOUT_FEC_RX_CLK,
116 PD15_AOUT_FEC_COL,
117 PD16_AIN_FEC_TX_ER,
118 PF23_AIN_FEC_TX_EN,
119 /* I2C2 */
120 PC5_PF_I2C2_SDA,
121 PC6_PF_I2C2_SCL,
122 /* FB */
123 PA5_PF_LSCLK,
124 PA6_PF_LD0,
125 PA7_PF_LD1,
126 PA8_PF_LD2,
127 PA9_PF_LD3,
128 PA10_PF_LD4,
129 PA11_PF_LD5,
130 PA12_PF_LD6,
131 PA13_PF_LD7,
132 PA14_PF_LD8,
133 PA15_PF_LD9,
134 PA16_PF_LD10,
135 PA17_PF_LD11,
136 PA18_PF_LD12,
137 PA19_PF_LD13,
138 PA20_PF_LD14,
139 PA21_PF_LD15,
140 PA22_PF_LD16,
141 PA23_PF_LD17,
142 PA24_PF_REV,
143 PA25_PF_CLS,
144 PA26_PF_PS,
145 PA27_PF_SPL_SPR,
146 PA28_PF_HSYNC,
147 PA29_PF_VSYNC,
148 PA30_PF_CONTRAST,
149 PA31_PF_OE_ACD,
150 /* OWIRE */
151 PE16_AF_OWIRE,
152 /* SDHC1*/
153 PE18_PF_SD1_D0,
154 PE19_PF_SD1_D1,
155 PE20_PF_SD1_D2,
156 PE21_PF_SD1_D3,
157 PE22_PF_SD1_CMD,
158 PE23_PF_SD1_CLK,
159 /* SDHC2*/
160 PB4_PF_SD2_D0,
161 PB5_PF_SD2_D1,
162 PB6_PF_SD2_D2,
163 PB7_PF_SD2_D3,
164 PB8_PF_SD2_CMD,
165 PB9_PF_SD2_CLK,
166};
167
168static const struct mxc_nand_platform_data
169mx27ads_nand_board_info __initconst = {
170 .width = 1,
171 .hw_ecc = 1,
172};
173
174/* ADS's NOR flash */
175static struct physmap_flash_data mx27ads_flash_data = {
176 .width = 2,
177};
178
179static struct resource mx27ads_flash_resource = {
180 .start = 0xc0000000,
181 .end = 0xc0000000 + 0x02000000 - 1,
182 .flags = IORESOURCE_MEM,
183
184};
185
186static struct platform_device mx27ads_nor_mtd_device = {
187 .name = "physmap-flash",
188 .id = 0,
189 .dev = {
190 .platform_data = &mx27ads_flash_data,
191 },
192 .num_resources = 1,
193 .resource = &mx27ads_flash_resource,
194};
195
196static const struct imxi2c_platform_data mx27ads_i2c1_data __initconst = {
197 .bitrate = 100000,
198};
199
200static struct i2c_board_info mx27ads_i2c_devices[] = {
201};
202
203void lcd_power(int on)
204{
205 if (on)
206 __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
207 else
208 __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
209}
210
211static struct imx_fb_videomode mx27ads_modes[] = {
212 {
213 .mode = {
214 .name = "Sharp-LQ035Q7",
215 .refresh = 60,
216 .xres = 240,
217 .yres = 320,
218 .pixclock = 188679, /* in ps (5.3MHz) */
219 .hsync_len = 1,
220 .left_margin = 9,
221 .right_margin = 16,
222 .vsync_len = 1,
223 .upper_margin = 7,
224 .lower_margin = 9,
225 },
226 .bpp = 16,
227 .pcr = 0xFB008BC0,
228 },
229};
230
231static struct imx_fb_platform_data mx27ads_fb_data = {
232 .mode = mx27ads_modes,
233 .num_modes = ARRAY_SIZE(mx27ads_modes),
234
235 /*
236 * - HSYNC active high
237 * - VSYNC active high
238 * - clk notenabled while idle
239 * - clock inverted
240 * - data not inverted
241 * - data enable low active
242 * - enable sharp mode
243 */
244 .pwmr = 0x00A903FF,
245 .lscr1 = 0x00120300,
246 .dmacr = 0x00020010,
247
248 .lcd_power = lcd_power,
249};
250
251static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
252 void *data)
253{
254 return request_irq(IRQ_GPIOE(21), detect_irq, IRQF_TRIGGER_RISING,
255 "sdhc1-card-detect", data);
256}
257
258static int mx27ads_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
259 void *data)
260{
261 return request_irq(IRQ_GPIOB(7), detect_irq, IRQF_TRIGGER_RISING,
262 "sdhc2-card-detect", data);
263}
264
265static void mx27ads_sdhc1_exit(struct device *dev, void *data)
266{
267 free_irq(IRQ_GPIOE(21), data);
268}
269
270static void mx27ads_sdhc2_exit(struct device *dev, void *data)
271{
272 free_irq(IRQ_GPIOB(7), data);
273}
274
275static struct imxmmc_platform_data sdhc1_pdata = {
276 .init = mx27ads_sdhc1_init,
277 .exit = mx27ads_sdhc1_exit,
278};
279
280static struct imxmmc_platform_data sdhc2_pdata = {
281 .init = mx27ads_sdhc2_init,
282 .exit = mx27ads_sdhc2_exit,
283};
284
285static struct platform_device *platform_devices[] __initdata = {
286 &mx27ads_nor_mtd_device,
287 &mxc_fec_device,
288 &mxc_w1_master_device,
289};
290
291static const struct imxuart_platform_data uart_pdata __initconst = {
292 .flags = IMXUART_HAVE_RTSCTS,
293};
294
295static void __init mx27ads_board_init(void)
296{
297 mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins),
298 "mx27ads");
299
300 imx27_add_imx_uart0(&uart_pdata);
301 imx27_add_imx_uart1(&uart_pdata);
302 imx27_add_imx_uart2(&uart_pdata);
303 imx27_add_imx_uart3(&uart_pdata);
304 imx27_add_imx_uart4(&uart_pdata);
305 imx27_add_imx_uart5(&uart_pdata);
306 imx27_add_mxc_nand(&mx27ads_nand_board_info);
307
308 /* only the i2c master 1 is used on this CPU card */
309 i2c_register_board_info(1, mx27ads_i2c_devices,
310 ARRAY_SIZE(mx27ads_i2c_devices));
311 imx27_add_i2c_imx1(&mx27ads_i2c1_data);
312 mxc_register_device(&mxc_fb_device, &mx27ads_fb_data);
313 mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
314 mxc_register_device(&mxc_sdhc_device1, &sdhc2_pdata);
315
316 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
317}
318
319static void __init mx27ads_timer_init(void)
320{
321 unsigned long fref = 26000000;
322
323 if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
324 fref = 27000000;
325
326 mx27_clocks_init(fref);
327}
328
329static struct sys_timer mx27ads_timer = {
330 .init = mx27ads_timer_init,
331};
332
333static struct map_desc mx27ads_io_desc[] __initdata = {
334 {
335 .virtual = PBC_BASE_ADDRESS,
336 .pfn = __phys_to_pfn(MX27_CS4_BASE_ADDR),
337 .length = SZ_1M,
338 .type = MT_DEVICE,
339 },
340};
341
342static void __init mx27ads_map_io(void)
343{
344 mx27_map_io();
345 iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
346}
347
348MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
349 /* maintainer: Freescale Semiconductor, Inc. */
350 .phys_io = MX27_AIPI_BASE_ADDR,
351 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
352 .boot_params = MX27_PHYS_OFFSET + 0x100,
353 .map_io = mx27ads_map_io,
354 .init_irq = mx27_init_irq,
355 .init_machine = mx27ads_board_init,
356 .timer = &mx27ads_timer,
357MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mxt_td60.c b/arch/arm/mach-imx/mach-mxt_td60.c
new file mode 100644
index 000000000000..a3a1e452d4c5
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mxt_td60.c
@@ -0,0 +1,285 @@
1/*
2 * Copyright (C) 2000 Deep Blue Solutions Ltd
3 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
4 * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/platform_device.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/map.h>
20#include <linux/mtd/partitions.h>
21#include <linux/mtd/physmap.h>
22#include <linux/i2c.h>
23#include <linux/irq.h>
24#include <mach/common.h>
25#include <mach/hardware.h>
26#include <asm/mach-types.h>
27#include <asm/mach/arch.h>
28#include <asm/mach/time.h>
29#include <asm/mach/map.h>
30#include <linux/gpio.h>
31#include <mach/iomux-mx27.h>
32#include <mach/mxc_nand.h>
33#include <linux/i2c/pca953x.h>
34#include <mach/imxfb.h>
35#include <mach/mmc.h>
36
37#include "devices-imx27.h"
38#include "devices.h"
39
40static unsigned int mxt_td60_pins[] __initdata = {
41 /* UART0 */
42 PE12_PF_UART1_TXD,
43 PE13_PF_UART1_RXD,
44 PE14_PF_UART1_CTS,
45 PE15_PF_UART1_RTS,
46 /* UART1 */
47 PE3_PF_UART2_CTS,
48 PE4_PF_UART2_RTS,
49 PE6_PF_UART2_TXD,
50 PE7_PF_UART2_RXD,
51 /* UART2 */
52 PE8_PF_UART3_TXD,
53 PE9_PF_UART3_RXD,
54 PE10_PF_UART3_CTS,
55 PE11_PF_UART3_RTS,
56 /* FEC */
57 PD0_AIN_FEC_TXD0,
58 PD1_AIN_FEC_TXD1,
59 PD2_AIN_FEC_TXD2,
60 PD3_AIN_FEC_TXD3,
61 PD4_AOUT_FEC_RX_ER,
62 PD5_AOUT_FEC_RXD1,
63 PD6_AOUT_FEC_RXD2,
64 PD7_AOUT_FEC_RXD3,
65 PD8_AF_FEC_MDIO,
66 PD9_AIN_FEC_MDC,
67 PD10_AOUT_FEC_CRS,
68 PD11_AOUT_FEC_TX_CLK,
69 PD12_AOUT_FEC_RXD0,
70 PD13_AOUT_FEC_RX_DV,
71 PD14_AOUT_FEC_RX_CLK,
72 PD15_AOUT_FEC_COL,
73 PD16_AIN_FEC_TX_ER,
74 PF23_AIN_FEC_TX_EN,
75 /* I2C1 */
76 PD17_PF_I2C_DATA,
77 PD18_PF_I2C_CLK,
78 /* I2C2 */
79 PC5_PF_I2C2_SDA,
80 PC6_PF_I2C2_SCL,
81 /* FB */
82 PA5_PF_LSCLK,
83 PA6_PF_LD0,
84 PA7_PF_LD1,
85 PA8_PF_LD2,
86 PA9_PF_LD3,
87 PA10_PF_LD4,
88 PA11_PF_LD5,
89 PA12_PF_LD6,
90 PA13_PF_LD7,
91 PA14_PF_LD8,
92 PA15_PF_LD9,
93 PA16_PF_LD10,
94 PA17_PF_LD11,
95 PA18_PF_LD12,
96 PA19_PF_LD13,
97 PA20_PF_LD14,
98 PA21_PF_LD15,
99 PA22_PF_LD16,
100 PA23_PF_LD17,
101 PA25_PF_CLS,
102 PA27_PF_SPL_SPR,
103 PA28_PF_HSYNC,
104 PA29_PF_VSYNC,
105 PA30_PF_CONTRAST,
106 PA31_PF_OE_ACD,
107 /* OWIRE */
108 PE16_AF_OWIRE,
109 /* SDHC1*/
110 PE18_PF_SD1_D0,
111 PE19_PF_SD1_D1,
112 PE20_PF_SD1_D2,
113 PE21_PF_SD1_D3,
114 PE22_PF_SD1_CMD,
115 PE23_PF_SD1_CLK,
116 PF8_AF_ATA_IORDY,
117 /* SDHC2*/
118 PB4_PF_SD2_D0,
119 PB5_PF_SD2_D1,
120 PB6_PF_SD2_D2,
121 PB7_PF_SD2_D3,
122 PB8_PF_SD2_CMD,
123 PB9_PF_SD2_CLK,
124};
125
126static const struct mxc_nand_platform_data
127mxt_td60_nand_board_info __initconst = {
128 .width = 1,
129 .hw_ecc = 1,
130};
131
132static const struct imxi2c_platform_data mxt_td60_i2c0_data __initconst = {
133 .bitrate = 100000,
134};
135
136/* PCA9557 */
137static int mxt_td60_pca9557_setup(struct i2c_client *client,
138 unsigned gpio_base, unsigned ngpio,
139 void *context)
140{
141 static int mxt_td60_gpio_value[] = {
142 -1, -1, -1, -1, -1, -1, -1, 1
143 };
144 int n;
145
146 for (n = 0; n < ARRAY_SIZE(mxt_td60_gpio_value); ++n) {
147 gpio_request(gpio_base + n, "MXT_TD60 GPIO Exp");
148 if (mxt_td60_gpio_value[n] < 0)
149 gpio_direction_input(gpio_base + n);
150 else
151 gpio_direction_output(gpio_base + n,
152 mxt_td60_gpio_value[n]);
153 gpio_export(gpio_base + n, 0);
154 }
155
156 return 0;
157}
158
159static struct pca953x_platform_data mxt_td60_pca9557_pdata = {
160 .gpio_base = 240, /* place PCA9557 after all MX27 gpio pins */
161 .invert = 0, /* Do not invert */
162 .setup = mxt_td60_pca9557_setup,
163};
164
165static struct i2c_board_info mxt_td60_i2c_devices[] = {
166 {
167 I2C_BOARD_INFO("pca9557", 0x18),
168 .platform_data = &mxt_td60_pca9557_pdata,
169 },
170};
171
172static const struct imxi2c_platform_data mxt_td60_i2c1_data __initconst = {
173 .bitrate = 100000,
174};
175
176static struct i2c_board_info mxt_td60_i2c2_devices[] = {
177};
178
179static struct imx_fb_videomode mxt_td60_modes[] = {
180 {
181 .mode = {
182 .name = "Chimei LW700AT9003",
183 .refresh = 60,
184 .xres = 800,
185 .yres = 480,
186 .pixclock = 30303,
187 .hsync_len = 64,
188 .left_margin = 0x67,
189 .right_margin = 0x68,
190 .vsync_len = 16,
191 .upper_margin = 0x0f,
192 .lower_margin = 0x0f,
193 },
194 .bpp = 16,
195 .pcr = 0xFA208B83,
196 },
197};
198
199static struct imx_fb_platform_data mxt_td60_fb_data = {
200 .mode = mxt_td60_modes,
201 .num_modes = ARRAY_SIZE(mxt_td60_modes),
202
203 /*
204 * - HSYNC active high
205 * - VSYNC active high
206 * - clk notenabled while idle
207 * - clock inverted
208 * - data not inverted
209 * - data enable low active
210 * - enable sharp mode
211 */
212 .pwmr = 0x00A903FF,
213 .lscr1 = 0x00120300,
214 .dmacr = 0x00020010,
215};
216
217static int mxt_td60_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
218 void *data)
219{
220 return request_irq(IRQ_GPIOF(8), detect_irq, IRQF_TRIGGER_FALLING,
221 "sdhc1-card-detect", data);
222}
223
224static void mxt_td60_sdhc1_exit(struct device *dev, void *data)
225{
226 free_irq(IRQ_GPIOF(8), data);
227}
228
229static struct imxmmc_platform_data sdhc1_pdata = {
230 .init = mxt_td60_sdhc1_init,
231 .exit = mxt_td60_sdhc1_exit,
232};
233
234static struct platform_device *platform_devices[] __initdata = {
235 &mxc_fec_device,
236};
237
238static const struct imxuart_platform_data uart_pdata __initconst = {
239 .flags = IMXUART_HAVE_RTSCTS,
240};
241
242static void __init mxt_td60_board_init(void)
243{
244 mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins),
245 "MXT_TD60");
246
247 imx27_add_imx_uart0(&uart_pdata);
248 imx27_add_imx_uart1(&uart_pdata);
249 imx27_add_imx_uart2(&uart_pdata);
250 imx27_add_mxc_nand(&mxt_td60_nand_board_info);
251
252 i2c_register_board_info(0, mxt_td60_i2c_devices,
253 ARRAY_SIZE(mxt_td60_i2c_devices));
254
255 i2c_register_board_info(1, mxt_td60_i2c2_devices,
256 ARRAY_SIZE(mxt_td60_i2c2_devices));
257
258 imx27_add_i2c_imx0(&mxt_td60_i2c0_data);
259 imx27_add_i2c_imx1(&mxt_td60_i2c1_data);
260 mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data);
261 mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
262
263 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
264}
265
266static void __init mxt_td60_timer_init(void)
267{
268 mx27_clocks_init(26000000);
269}
270
271static struct sys_timer mxt_td60_timer = {
272 .init = mxt_td60_timer_init,
273};
274
275MACHINE_START(MXT_TD60, "Maxtrack i-MXT TD60")
276 /* maintainer: Maxtrack Industrial */
277 .phys_io = MX27_AIPI_BASE_ADDR,
278 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
279 .boot_params = MX27_PHYS_OFFSET + 0x100,
280 .map_io = mx27_map_io,
281 .init_irq = mx27_init_irq,
282 .init_machine = mxt_td60_board_init,
283 .timer = &mxt_td60_timer,
284MACHINE_END
285
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
new file mode 100644
index 000000000000..6c92deaf468f
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -0,0 +1,460 @@
1/*
2 * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
3 * Copyright (C) 2009 Sascha Hauer (kernel@pengutronix.de)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301, USA.
18 */
19
20#include <linux/platform_device.h>
21#include <linux/io.h>
22#include <linux/i2c.h>
23#include <linux/i2c/at24.h>
24#include <linux/dma-mapping.h>
25#include <linux/spi/spi.h>
26#include <linux/spi/eeprom.h>
27#include <linux/irq.h>
28#include <linux/delay.h>
29#include <linux/gpio.h>
30#include <linux/usb/otg.h>
31#include <linux/usb/ulpi.h>
32#include <linux/fsl_devices.h>
33
34#include <asm/mach/arch.h>
35#include <asm/mach-types.h>
36#include <mach/common.h>
37#include <mach/hardware.h>
38#include <mach/iomux-mx27.h>
39#include <asm/mach/time.h>
40#include <mach/audmux.h>
41#include <mach/ssi.h>
42#include <mach/mxc_nand.h>
43#include <mach/irqs.h>
44#include <mach/mmc.h>
45#include <mach/mxc_ehci.h>
46#include <mach/ulpi.h>
47#include <mach/imxfb.h>
48
49#include "devices-imx27.h"
50#include "devices.h"
51
52#define OTG_PHY_CS_GPIO (GPIO_PORTB + 23)
53#define USBH2_PHY_CS_GPIO (GPIO_PORTB + 24)
54#define SPI1_SS0 (GPIO_PORTD + 28)
55#define SPI1_SS1 (GPIO_PORTD + 27)
56#define SD2_CD (GPIO_PORTC + 29)
57
58static int pca100_pins[] = {
59 /* UART1 */
60 PE12_PF_UART1_TXD,
61 PE13_PF_UART1_RXD,
62 PE14_PF_UART1_CTS,
63 PE15_PF_UART1_RTS,
64 /* SDHC */
65 PB4_PF_SD2_D0,
66 PB5_PF_SD2_D1,
67 PB6_PF_SD2_D2,
68 PB7_PF_SD2_D3,
69 PB8_PF_SD2_CMD,
70 PB9_PF_SD2_CLK,
71 SD2_CD | GPIO_GPIO | GPIO_IN,
72 /* FEC */
73 PD0_AIN_FEC_TXD0,
74 PD1_AIN_FEC_TXD1,
75 PD2_AIN_FEC_TXD2,
76 PD3_AIN_FEC_TXD3,
77 PD4_AOUT_FEC_RX_ER,
78 PD5_AOUT_FEC_RXD1,
79 PD6_AOUT_FEC_RXD2,
80 PD7_AOUT_FEC_RXD3,
81 PD8_AF_FEC_MDIO,
82 PD9_AIN_FEC_MDC,
83 PD10_AOUT_FEC_CRS,
84 PD11_AOUT_FEC_TX_CLK,
85 PD12_AOUT_FEC_RXD0,
86 PD13_AOUT_FEC_RX_DV,
87 PD14_AOUT_FEC_RX_CLK,
88 PD15_AOUT_FEC_COL,
89 PD16_AIN_FEC_TX_ER,
90 PF23_AIN_FEC_TX_EN,
91 /* SSI1 */
92 PC20_PF_SSI1_FS,
93 PC21_PF_SSI1_RXD,
94 PC22_PF_SSI1_TXD,
95 PC23_PF_SSI1_CLK,
96 /* onboard I2C */
97 PC5_PF_I2C2_SDA,
98 PC6_PF_I2C2_SCL,
99 /* external I2C */
100 PD17_PF_I2C_DATA,
101 PD18_PF_I2C_CLK,
102 /* SPI1 */
103 PD25_PF_CSPI1_RDY,
104 PD29_PF_CSPI1_SCLK,
105 PD30_PF_CSPI1_MISO,
106 PD31_PF_CSPI1_MOSI,
107 /* OTG */
108 OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
109 PC7_PF_USBOTG_DATA5,
110 PC8_PF_USBOTG_DATA6,
111 PC9_PF_USBOTG_DATA0,
112 PC10_PF_USBOTG_DATA2,
113 PC11_PF_USBOTG_DATA1,
114 PC12_PF_USBOTG_DATA4,
115 PC13_PF_USBOTG_DATA3,
116 PE0_PF_USBOTG_NXT,
117 PE1_PF_USBOTG_STP,
118 PE2_PF_USBOTG_DIR,
119 PE24_PF_USBOTG_CLK,
120 PE25_PF_USBOTG_DATA7,
121 /* USBH2 */
122 USBH2_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
123 PA0_PF_USBH2_CLK,
124 PA1_PF_USBH2_DIR,
125 PA2_PF_USBH2_DATA7,
126 PA3_PF_USBH2_NXT,
127 PA4_PF_USBH2_STP,
128 PD19_AF_USBH2_DATA4,
129 PD20_AF_USBH2_DATA3,
130 PD21_AF_USBH2_DATA6,
131 PD22_AF_USBH2_DATA0,
132 PD23_AF_USBH2_DATA2,
133 PD24_AF_USBH2_DATA1,
134 PD26_AF_USBH2_DATA5,
135 /* display */
136 PA5_PF_LSCLK,
137 PA6_PF_LD0,
138 PA7_PF_LD1,
139 PA8_PF_LD2,
140 PA9_PF_LD3,
141 PA10_PF_LD4,
142 PA11_PF_LD5,
143 PA12_PF_LD6,
144 PA13_PF_LD7,
145 PA14_PF_LD8,
146 PA15_PF_LD9,
147 PA16_PF_LD10,
148 PA17_PF_LD11,
149 PA18_PF_LD12,
150 PA19_PF_LD13,
151 PA20_PF_LD14,
152 PA21_PF_LD15,
153 PA22_PF_LD16,
154 PA23_PF_LD17,
155 PA26_PF_PS,
156 PA28_PF_HSYNC,
157 PA29_PF_VSYNC,
158 PA31_PF_OE_ACD,
159 /* free GPIO */
160 GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN, /* GPIO0_IRQ */
161 GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN, /* GPIO1_IRQ */
162 GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN, /* GPIO2_IRQ */
163};
164
165static const struct imxuart_platform_data uart_pdata __initconst = {
166 .flags = IMXUART_HAVE_RTSCTS,
167};
168
169static const struct mxc_nand_platform_data
170pca100_nand_board_info __initconst = {
171 .width = 1,
172 .hw_ecc = 1,
173};
174
175static struct platform_device *platform_devices[] __initdata = {
176 &mxc_w1_master_device,
177 &mxc_fec_device,
178 &mxc_wdt,
179};
180
181static const struct imxi2c_platform_data pca100_i2c1_data __initconst = {
182 .bitrate = 100000,
183};
184
185static struct at24_platform_data board_eeprom = {
186 .byte_len = 4096,
187 .page_size = 32,
188 .flags = AT24_FLAG_ADDR16,
189};
190
191static struct i2c_board_info pca100_i2c_devices[] = {
192 {
193 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
194 .platform_data = &board_eeprom,
195 }, {
196 I2C_BOARD_INFO("rtc-pcf8563", 0x51),
197 .type = "pcf8563"
198 }, {
199 I2C_BOARD_INFO("lm75", 0x4a),
200 .type = "lm75"
201 }
202};
203
204#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
205static struct spi_eeprom at25320 = {
206 .name = "at25320an",
207 .byte_len = 4096,
208 .page_size = 32,
209 .flags = EE_ADDR2,
210};
211
212static struct spi_board_info pca100_spi_board_info[] __initdata = {
213 {
214 .modalias = "at25",
215 .max_speed_hz = 30000,
216 .bus_num = 0,
217 .chip_select = 1,
218 .platform_data = &at25320,
219 },
220};
221
222static int pca100_spi_cs[] = {SPI1_SS0, SPI1_SS1};
223
224static const struct spi_imx_master pca100_spi0_data __initconst = {
225 .chipselect = pca100_spi_cs,
226 .num_chipselect = ARRAY_SIZE(pca100_spi_cs),
227};
228#endif
229
230static void pca100_ac97_warm_reset(struct snd_ac97 *ac97)
231{
232 mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT);
233 gpio_set_value(GPIO_PORTC + 20, 1);
234 udelay(2);
235 gpio_set_value(GPIO_PORTC + 20, 0);
236 mxc_gpio_mode(PC20_PF_SSI1_FS);
237 msleep(2);
238}
239
240static void pca100_ac97_cold_reset(struct snd_ac97 *ac97)
241{
242 mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT); /* FS */
243 gpio_set_value(GPIO_PORTC + 20, 0);
244 mxc_gpio_mode(GPIO_PORTC | 22 | GPIO_GPIO | GPIO_OUT); /* TX */
245 gpio_set_value(GPIO_PORTC + 22, 0);
246 mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_OUT); /* reset */
247 gpio_set_value(GPIO_PORTC + 28, 0);
248 udelay(10);
249 gpio_set_value(GPIO_PORTC + 28, 1);
250 mxc_gpio_mode(PC20_PF_SSI1_FS);
251 mxc_gpio_mode(PC22_PF_SSI1_TXD);
252 msleep(2);
253}
254
255static struct imx_ssi_platform_data pca100_ssi_pdata = {
256 .ac97_reset = pca100_ac97_cold_reset,
257 .ac97_warm_reset = pca100_ac97_warm_reset,
258 .flags = IMX_SSI_USE_AC97,
259};
260
261static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
262 void *data)
263{
264 int ret;
265
266 ret = request_irq(IRQ_GPIOC(29), detect_irq,
267 IRQF_DISABLED | IRQF_TRIGGER_FALLING,
268 "imx-mmc-detect", data);
269 if (ret)
270 printk(KERN_ERR
271 "pca100: Failed to reuest irq for sd/mmc detection\n");
272
273 return ret;
274}
275
276static void pca100_sdhc2_exit(struct device *dev, void *data)
277{
278 free_irq(IRQ_GPIOC(29), data);
279}
280
281static struct imxmmc_platform_data sdhc_pdata = {
282 .init = pca100_sdhc2_init,
283 .exit = pca100_sdhc2_exit,
284};
285
286#if defined(CONFIG_USB_ULPI)
287static int otg_phy_init(struct platform_device *pdev)
288{
289 gpio_set_value(OTG_PHY_CS_GPIO, 0);
290 return 0;
291}
292
293static struct mxc_usbh_platform_data otg_pdata = {
294 .init = otg_phy_init,
295 .portsc = MXC_EHCI_MODE_ULPI,
296 .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
297};
298
299static int usbh2_phy_init(struct platform_device *pdev)
300{
301 gpio_set_value(USBH2_PHY_CS_GPIO, 0);
302 return 0;
303}
304
305static struct mxc_usbh_platform_data usbh2_pdata = {
306 .init = usbh2_phy_init,
307 .portsc = MXC_EHCI_MODE_ULPI,
308 .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
309};
310#endif
311
312static struct fsl_usb2_platform_data otg_device_pdata = {
313 .operating_mode = FSL_USB2_DR_DEVICE,
314 .phy_mode = FSL_USB2_PHY_ULPI,
315};
316
317static int otg_mode_host;
318
319static int __init pca100_otg_mode(char *options)
320{
321 if (!strcmp(options, "host"))
322 otg_mode_host = 1;
323 else if (!strcmp(options, "device"))
324 otg_mode_host = 0;
325 else
326 pr_info("otg_mode neither \"host\" nor \"device\". "
327 "Defaulting to device\n");
328 return 0;
329}
330__setup("otg_mode=", pca100_otg_mode);
331
332/* framebuffer info */
333static struct imx_fb_videomode pca100_fb_modes[] = {
334 {
335 .mode = {
336 .name = "EMERGING-ETV570G0DHU",
337 .refresh = 60,
338 .xres = 640,
339 .yres = 480,
340 .pixclock = 39722, /* in ps (25.175 MHz) */
341 .hsync_len = 30,
342 .left_margin = 114,
343 .right_margin = 16,
344 .vsync_len = 3,
345 .upper_margin = 32,
346 .lower_margin = 0,
347 },
348 /*
349 * TFT
350 * Pixel pol active high
351 * HSYNC active low
352 * VSYNC active low
353 * use HSYNC for ACD count
354 * line clock disable while idle
355 * always enable line clock even if no data
356 */
357 .pcr = 0xf0c08080,
358 .bpp = 16,
359 },
360};
361
362static struct imx_fb_platform_data pca100_fb_data = {
363 .mode = pca100_fb_modes,
364 .num_modes = ARRAY_SIZE(pca100_fb_modes),
365
366 .pwmr = 0x00A903FF,
367 .lscr1 = 0x00120300,
368 .dmacr = 0x00020010,
369};
370
371static void __init pca100_init(void)
372{
373 int ret;
374
375 /* SSI unit */
376 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
377 MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
378 MXC_AUDMUX_V1_PCR_TFCSEL(3) |
379 MXC_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
380 MXC_AUDMUX_V1_PCR_RXDSEL(3));
381 mxc_audmux_v1_configure_port(3,
382 MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
383 MXC_AUDMUX_V1_PCR_TFCSEL(0) |
384 MXC_AUDMUX_V1_PCR_TFSDIR |
385 MXC_AUDMUX_V1_PCR_RXDSEL(0));
386
387 ret = mxc_gpio_setup_multiple_pins(pca100_pins,
388 ARRAY_SIZE(pca100_pins), "PCA100");
389 if (ret)
390 printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret);
391
392 mxc_register_device(&imx_ssi_device0, &pca100_ssi_pdata);
393
394 imx27_add_imx_uart0(&uart_pdata);
395
396 mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
397
398 imx27_add_mxc_nand(&pca100_nand_board_info);
399
400 /* only the i2c master 1 is used on this CPU card */
401 i2c_register_board_info(1, pca100_i2c_devices,
402 ARRAY_SIZE(pca100_i2c_devices));
403
404 imx27_add_i2c_imx1(&pca100_i2c1_data);
405
406#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
407 mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_IN);
408 mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN);
409 spi_register_board_info(pca100_spi_board_info,
410 ARRAY_SIZE(pca100_spi_board_info));
411 imx27_add_spi_imx0(&pca100_spi_0_data);
412#endif
413
414 gpio_request(OTG_PHY_CS_GPIO, "usb-otg-cs");
415 gpio_direction_output(OTG_PHY_CS_GPIO, 1);
416 gpio_request(USBH2_PHY_CS_GPIO, "usb-host2-cs");
417 gpio_direction_output(USBH2_PHY_CS_GPIO, 1);
418
419#if defined(CONFIG_USB_ULPI)
420 if (otg_mode_host) {
421 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
422 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
423
424 mxc_register_device(&mxc_otg_host, &otg_pdata);
425 }
426
427 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
428 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
429
430 mxc_register_device(&mxc_usbh2, &usbh2_pdata);
431#endif
432 if (!otg_mode_host) {
433 gpio_set_value(OTG_PHY_CS_GPIO, 0);
434 mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
435 }
436
437 mxc_register_device(&mxc_fb_device, &pca100_fb_data);
438
439 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
440}
441
442static void __init pca100_timer_init(void)
443{
444 mx27_clocks_init(26000000);
445}
446
447static struct sys_timer pca100_timer = {
448 .init = pca100_timer_init,
449};
450
451MACHINE_START(PCA100, "phyCARD-i.MX27")
452 .phys_io = MX27_AIPI_BASE_ADDR,
453 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
454 .boot_params = MX27_PHYS_OFFSET + 0x100,
455 .map_io = mx27_map_io,
456 .init_irq = mx27_init_irq,
457 .init_machine = pca100_init,
458 .timer = &pca100_timer,
459MACHINE_END
460
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c
new file mode 100644
index 000000000000..9212e8f37001
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pcm038.c
@@ -0,0 +1,352 @@
1/*
2 * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
3 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301, USA.
18 */
19
20#include <linux/i2c.h>
21#include <linux/i2c/at24.h>
22#include <linux/io.h>
23#include <linux/mtd/plat-ram.h>
24#include <linux/mtd/physmap.h>
25#include <linux/platform_device.h>
26#include <linux/regulator/machine.h>
27#include <linux/mfd/mc13783.h>
28#include <linux/spi/spi.h>
29#include <linux/irq.h>
30
31#include <asm/mach-types.h>
32#include <asm/mach/arch.h>
33#include <asm/mach/time.h>
34
35#include <mach/board-pcm038.h>
36#include <mach/common.h>
37#include <mach/hardware.h>
38#include <mach/iomux-mx27.h>
39#include <mach/mxc_nand.h>
40#include <mach/mxc_ehci.h>
41#include <mach/ulpi.h>
42
43#include "devices-imx27.h"
44#include "devices.h"
45
46static int pcm038_pins[] = {
47 /* UART1 */
48 PE12_PF_UART1_TXD,
49 PE13_PF_UART1_RXD,
50 PE14_PF_UART1_CTS,
51 PE15_PF_UART1_RTS,
52 /* UART2 */
53 PE3_PF_UART2_CTS,
54 PE4_PF_UART2_RTS,
55 PE6_PF_UART2_TXD,
56 PE7_PF_UART2_RXD,
57 /* UART3 */
58 PE8_PF_UART3_TXD,
59 PE9_PF_UART3_RXD,
60 PE10_PF_UART3_CTS,
61 PE11_PF_UART3_RTS,
62 /* FEC */
63 PD0_AIN_FEC_TXD0,
64 PD1_AIN_FEC_TXD1,
65 PD2_AIN_FEC_TXD2,
66 PD3_AIN_FEC_TXD3,
67 PD4_AOUT_FEC_RX_ER,
68 PD5_AOUT_FEC_RXD1,
69 PD6_AOUT_FEC_RXD2,
70 PD7_AOUT_FEC_RXD3,
71 PD8_AF_FEC_MDIO,
72 PD9_AIN_FEC_MDC,
73 PD10_AOUT_FEC_CRS,
74 PD11_AOUT_FEC_TX_CLK,
75 PD12_AOUT_FEC_RXD0,
76 PD13_AOUT_FEC_RX_DV,
77 PD14_AOUT_FEC_RX_CLK,
78 PD15_AOUT_FEC_COL,
79 PD16_AIN_FEC_TX_ER,
80 PF23_AIN_FEC_TX_EN,
81 /* I2C2 */
82 PC5_PF_I2C2_SDA,
83 PC6_PF_I2C2_SCL,
84 /* SPI1 */
85 PD25_PF_CSPI1_RDY,
86 PD29_PF_CSPI1_SCLK,
87 PD30_PF_CSPI1_MISO,
88 PD31_PF_CSPI1_MOSI,
89 /* SSI1 */
90 PC20_PF_SSI1_FS,
91 PC21_PF_SSI1_RXD,
92 PC22_PF_SSI1_TXD,
93 PC23_PF_SSI1_CLK,
94 /* SSI4 */
95 PC16_PF_SSI4_FS,
96 PC17_PF_SSI4_RXD,
97 PC18_PF_SSI4_TXD,
98 PC19_PF_SSI4_CLK,
99 /* USB host */
100 PA0_PF_USBH2_CLK,
101 PA1_PF_USBH2_DIR,
102 PA2_PF_USBH2_DATA7,
103 PA3_PF_USBH2_NXT,
104 PA4_PF_USBH2_STP,
105 PD19_AF_USBH2_DATA4,
106 PD20_AF_USBH2_DATA3,
107 PD21_AF_USBH2_DATA6,
108 PD22_AF_USBH2_DATA0,
109 PD23_AF_USBH2_DATA2,
110 PD24_AF_USBH2_DATA1,
111 PD26_AF_USBH2_DATA5,
112};
113
114/*
115 * Phytec's PCM038 comes with 2MiB battery buffered SRAM,
116 * 16 bit width
117 */
118
119static struct platdata_mtd_ram pcm038_sram_data = {
120 .bankwidth = 2,
121};
122
123static struct resource pcm038_sram_resource = {
124 .start = MX27_CS1_BASE_ADDR,
125 .end = MX27_CS1_BASE_ADDR + 512 * 1024 - 1,
126 .flags = IORESOURCE_MEM,
127};
128
129static struct platform_device pcm038_sram_mtd_device = {
130 .name = "mtd-ram",
131 .id = 0,
132 .dev = {
133 .platform_data = &pcm038_sram_data,
134 },
135 .num_resources = 1,
136 .resource = &pcm038_sram_resource,
137};
138
139/*
140 * Phytec's phyCORE-i.MX27 comes with 32MiB flash,
141 * 16 bit width
142 */
143static struct physmap_flash_data pcm038_flash_data = {
144 .width = 2,
145};
146
147static struct resource pcm038_flash_resource = {
148 .start = 0xc0000000,
149 .end = 0xc1ffffff,
150 .flags = IORESOURCE_MEM,
151};
152
153static struct platform_device pcm038_nor_mtd_device = {
154 .name = "physmap-flash",
155 .id = 0,
156 .dev = {
157 .platform_data = &pcm038_flash_data,
158 },
159 .num_resources = 1,
160 .resource = &pcm038_flash_resource,
161};
162
163static const struct imxuart_platform_data uart_pdata __initconst = {
164 .flags = IMXUART_HAVE_RTSCTS,
165};
166
167static const struct mxc_nand_platform_data
168pcm038_nand_board_info __initconst = {
169 .width = 1,
170 .hw_ecc = 1,
171};
172
173static struct platform_device *platform_devices[] __initdata = {
174 &pcm038_nor_mtd_device,
175 &mxc_w1_master_device,
176 &mxc_fec_device,
177 &pcm038_sram_mtd_device,
178 &mxc_wdt,
179};
180
181/* On pcm038 there's a sram attached to CS1, we enable the chipselect here and
182 * setup other stuffs to access the sram. */
183static void __init pcm038_init_sram(void)
184{
185 mx27_setup_weimcs(1, 0x0000d843, 0x22252521, 0x22220a00);
186}
187
188static const struct imxi2c_platform_data pcm038_i2c1_data __initconst = {
189 .bitrate = 100000,
190};
191
192static struct at24_platform_data board_eeprom = {
193 .byte_len = 4096,
194 .page_size = 32,
195 .flags = AT24_FLAG_ADDR16,
196};
197
198static struct i2c_board_info pcm038_i2c_devices[] = {
199 {
200 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
201 .platform_data = &board_eeprom,
202 }, {
203 I2C_BOARD_INFO("pcf8563", 0x51),
204 }, {
205 I2C_BOARD_INFO("lm75", 0x4a),
206 }
207};
208
209static int pcm038_spi_cs[] = {GPIO_PORTD + 28};
210
211static const struct spi_imx_master pcm038_spi0_data __initconst = {
212 .chipselect = pcm038_spi_cs,
213 .num_chipselect = ARRAY_SIZE(pcm038_spi_cs),
214};
215
216static struct regulator_consumer_supply sdhc1_consumers[] = {
217 {
218 .dev = &mxc_sdhc_device1.dev,
219 .supply = "sdhc_vcc",
220 },
221};
222
223static struct regulator_init_data sdhc1_data = {
224 .constraints = {
225 .min_uV = 3000000,
226 .max_uV = 3400000,
227 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
228 REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
229 .valid_modes_mask = REGULATOR_MODE_NORMAL |
230 REGULATOR_MODE_FAST,
231 .always_on = 0,
232 .boot_on = 0,
233 },
234 .num_consumer_supplies = ARRAY_SIZE(sdhc1_consumers),
235 .consumer_supplies = sdhc1_consumers,
236};
237
238static struct regulator_consumer_supply cam_consumers[] = {
239 {
240 .dev = NULL,
241 .supply = "imx_cam_vcc",
242 },
243};
244
245static struct regulator_init_data cam_data = {
246 .constraints = {
247 .min_uV = 3000000,
248 .max_uV = 3400000,
249 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
250 REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
251 .valid_modes_mask = REGULATOR_MODE_NORMAL |
252 REGULATOR_MODE_FAST,
253 .always_on = 0,
254 .boot_on = 0,
255 },
256 .num_consumer_supplies = ARRAY_SIZE(cam_consumers),
257 .consumer_supplies = cam_consumers,
258};
259
260struct mc13783_regulator_init_data pcm038_regulators[] = {
261 {
262 .id = MC13783_REGU_VCAM,
263 .init_data = &cam_data,
264 }, {
265 .id = MC13783_REGU_VMMC1,
266 .init_data = &sdhc1_data,
267 },
268};
269
270static struct mc13783_platform_data pcm038_pmic = {
271 .regulators = pcm038_regulators,
272 .num_regulators = ARRAY_SIZE(pcm038_regulators),
273 .flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
274 MC13783_USE_TOUCHSCREEN,
275};
276
277static struct spi_board_info pcm038_spi_board_info[] __initdata = {
278 {
279 .modalias = "mc13783",
280 .irq = IRQ_GPIOB(23),
281 .max_speed_hz = 300000,
282 .bus_num = 0,
283 .chip_select = 0,
284 .platform_data = &pcm038_pmic,
285 .mode = SPI_CS_HIGH,
286 }
287};
288
289static struct mxc_usbh_platform_data usbh2_pdata = {
290 .portsc = MXC_EHCI_MODE_ULPI,
291 .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
292};
293
294static void __init pcm038_init(void)
295{
296 mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
297 "PCM038");
298
299 pcm038_init_sram();
300
301 imx27_add_imx_uart0(&uart_pdata);
302 imx27_add_imx_uart1(&uart_pdata);
303 imx27_add_imx_uart2(&uart_pdata);
304
305 mxc_gpio_mode(PE16_AF_OWIRE);
306 imx27_add_mxc_nand(&pcm038_nand_board_info);
307
308 /* only the i2c master 1 is used on this CPU card */
309 i2c_register_board_info(1, pcm038_i2c_devices,
310 ARRAY_SIZE(pcm038_i2c_devices));
311
312 imx27_add_i2c_imx1(&pcm038_i2c1_data);
313
314 /* PE18 for user-LED D40 */
315 mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
316
317 mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
318
319 /* MC13783 IRQ */
320 mxc_gpio_mode(GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN);
321
322 imx27_add_spi_imx0(&pcm038_spi0_data);
323 spi_register_board_info(pcm038_spi_board_info,
324 ARRAY_SIZE(pcm038_spi_board_info));
325
326 mxc_register_device(&mxc_usbh2, &usbh2_pdata);
327
328 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
329
330#ifdef CONFIG_MACH_PCM970_BASEBOARD
331 pcm970_baseboard_init();
332#endif
333}
334
335static void __init pcm038_timer_init(void)
336{
337 mx27_clocks_init(26000000);
338}
339
340static struct sys_timer pcm038_timer = {
341 .init = pcm038_timer_init,
342};
343
344MACHINE_START(PCM038, "phyCORE-i.MX27")
345 .phys_io = MX27_AIPI_BASE_ADDR,
346 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
347 .boot_params = MX27_PHYS_OFFSET + 0x100,
348 .map_io = mx27_map_io,
349 .init_irq = mx27_init_irq,
350 .init_machine = pcm038_init,
351 .timer = &pcm038_timer,
352MACHINE_END
diff --git a/arch/arm/mach-imx/mach-scb9328.c b/arch/arm/mach-imx/mach-scb9328.c
new file mode 100644
index 000000000000..88bf0d1e26e6
--- /dev/null
+++ b/arch/arm/mach-imx/mach-scb9328.c
@@ -0,0 +1,157 @@
1/*
2 * linux/arch/arm/mach-mx1/mach-scb9328.c
3 *
4 * Copyright (c) 2004 Sascha Hauer <saschahauer@web.de>
5 * Copyright (c) 2006-2008 Juergen Beisert <jbeisert@netscape.net>
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 */
12
13#include <linux/platform_device.h>
14#include <linux/mtd/physmap.h>
15#include <linux/interrupt.h>
16#include <linux/dm9000.h>
17
18#include <asm/mach-types.h>
19#include <asm/mach/arch.h>
20#include <asm/mach/time.h>
21
22#include <mach/common.h>
23#include <mach/hardware.h>
24#include <mach/irqs.h>
25#include <mach/iomux-mx1.h>
26
27#include "devices-imx1.h"
28#include "devices.h"
29
30/*
31 * This scb9328 has a 32MiB flash
32 */
33static struct resource flash_resource = {
34 .start = MX1_CS0_PHYS,
35 .end = MX1_CS0_PHYS + (32 * 1024 * 1024) - 1,
36 .flags = IORESOURCE_MEM,
37};
38
39static struct physmap_flash_data scb_flash_data = {
40 .width = 2,
41};
42
43static struct platform_device scb_flash_device = {
44 .name = "physmap-flash",
45 .id = 0,
46 .dev = {
47 .platform_data = &scb_flash_data,
48 },
49 .resource = &flash_resource,
50 .num_resources = 1,
51};
52
53/*
54 * scb9328 has a DM9000 network controller
55 * connected to CS5, with 16 bit data path
56 * and interrupt connected to GPIO 3
57 */
58
59/*
60 * internal datapath is fixed 16 bit
61 */
62static struct dm9000_plat_data dm9000_platdata = {
63 .flags = DM9000_PLATF_16BITONLY,
64};
65
66/*
67 * the DM9000 drivers wants two defined address spaces
68 * to gain access to address latch registers and the data path.
69 */
70static struct resource dm9000x_resources[] = {
71 {
72 .name = "address area",
73 .start = MX1_CS5_PHYS,
74 .end = MX1_CS5_PHYS + 1,
75 .flags = IORESOURCE_MEM, /* address access */
76 }, {
77 .name = "data area",
78 .start = MX1_CS5_PHYS + 4,
79 .end = MX1_CS5_PHYS + 5,
80 .flags = IORESOURCE_MEM, /* data access */
81 }, {
82 .start = IRQ_GPIOC(3),
83 .end = IRQ_GPIOC(3),
84 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
85 },
86};
87
88static struct platform_device dm9000x_device = {
89 .name = "dm9000",
90 .id = 0,
91 .num_resources = ARRAY_SIZE(dm9000x_resources),
92 .resource = dm9000x_resources,
93 .dev = {
94 .platform_data = &dm9000_platdata,
95 }
96};
97
98static int mxc_uart1_pins[] = {
99 PC9_PF_UART1_CTS,
100 PC10_PF_UART1_RTS,
101 PC11_PF_UART1_TXD,
102 PC12_PF_UART1_RXD,
103};
104
105static int uart1_mxc_init(struct platform_device *pdev)
106{
107 return mxc_gpio_setup_multiple_pins(mxc_uart1_pins,
108 ARRAY_SIZE(mxc_uart1_pins), "UART1");
109}
110
111static void uart1_mxc_exit(struct platform_device *pdev)
112{
113 mxc_gpio_release_multiple_pins(mxc_uart1_pins,
114 ARRAY_SIZE(mxc_uart1_pins));
115}
116
117static const struct imxuart_platform_data uart_pdata __initconst = {
118 .init = uart1_mxc_init,
119 .exit = uart1_mxc_exit,
120 .flags = IMXUART_HAVE_RTSCTS,
121};
122
123static struct platform_device *devices[] __initdata = {
124 &scb_flash_device,
125 &dm9000x_device,
126};
127
128/*
129 * scb9328_init - Init the CPU card itself
130 */
131static void __init scb9328_init(void)
132{
133 imx1_add_imx_uart0(&uart_pdata);
134
135 printk(KERN_INFO"Scb9328: Adding devices\n");
136 platform_add_devices(devices, ARRAY_SIZE(devices));
137}
138
139static void __init scb9328_timer_init(void)
140{
141 mx1_clocks_init(32000);
142}
143
144static struct sys_timer scb9328_timer = {
145 .init = scb9328_timer_init,
146};
147
148MACHINE_START(SCB9328, "Synertronixx scb9328")
149 /* Sascha Hauer */
150 .phys_io = 0x00200000,
151 .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc,
152 .boot_params = 0x08000100,
153 .map_io = mx1_map_io,
154 .init_irq = mx1_init_irq,
155 .timer = &scb9328_timer,
156 .init_machine = scb9328_init,
157MACHINE_END
diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c
new file mode 100644
index 000000000000..9be92b96dc89
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx1.c
@@ -0,0 +1,50 @@
1/*
2 * author: Sascha Hauer
3 * Created: april 20th, 2004
4 * Copyright: Synertronixx GmbH
5 *
6 * Common code for i.MX1 machines
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/io.h>
21
22#include <asm/mach/map.h>
23
24#include <mach/common.h>
25#include <mach/hardware.h>
26
27static struct map_desc imx_io_desc[] __initdata = {
28 {
29 .virtual = MX1_IO_BASE_ADDR_VIRT,
30 .pfn = __phys_to_pfn(MX1_IO_BASE_ADDR),
31 .length = MX1_IO_SIZE,
32 .type = MT_DEVICE
33 }
34};
35
36void __init mx1_map_io(void)
37{
38 mxc_set_cpu_type(MXC_CPU_MX1);
39 mxc_arch_reset_init(MX1_IO_ADDRESS(MX1_WDT_BASE_ADDR));
40
41 iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc));
42}
43
44int imx1_register_gpios(void);
45
46void __init mx1_init_irq(void)
47{
48 mxc_init_irq(MX1_IO_ADDRESS(MX1_AVIC_BASE_ADDR));
49 imx1_register_gpios();
50}
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
new file mode 100644
index 000000000000..12faeeaa0a97
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -0,0 +1,86 @@
1/*
2 * arch/arm/mach-imx/mm-imx21.c
3 *
4 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <linux/mm.h>
22#include <linux/init.h>
23#include <mach/hardware.h>
24#include <mach/common.h>
25#include <asm/pgtable.h>
26#include <asm/mach/map.h>
27
28/* MX21 memory map definition */
29static struct map_desc imx21_io_desc[] __initdata = {
30 /*
31 * this fixed mapping covers:
32 * - AIPI1
33 * - AIPI2
34 * - AITC
35 * - ROM Patch
36 * - and some reserved space
37 */
38 {
39 .virtual = MX21_AIPI_BASE_ADDR_VIRT,
40 .pfn = __phys_to_pfn(MX21_AIPI_BASE_ADDR),
41 .length = MX21_AIPI_SIZE,
42 .type = MT_DEVICE
43 },
44 /*
45 * this fixed mapping covers:
46 * - CSI
47 * - ATA
48 */
49 {
50 .virtual = MX21_SAHB1_BASE_ADDR_VIRT,
51 .pfn = __phys_to_pfn(MX21_SAHB1_BASE_ADDR),
52 .length = MX21_SAHB1_SIZE,
53 .type = MT_DEVICE
54 },
55 /*
56 * this fixed mapping covers:
57 * - EMI
58 */
59 {
60 .virtual = MX21_X_MEMC_BASE_ADDR_VIRT,
61 .pfn = __phys_to_pfn(MX21_X_MEMC_BASE_ADDR),
62 .length = MX21_X_MEMC_SIZE,
63 .type = MT_DEVICE
64 },
65};
66
67/*
68 * Initialize the memory map. It is called during the
69 * system startup to create static physical to virtual
70 * memory map for the IO modules.
71 */
72void __init mx21_map_io(void)
73{
74 mxc_set_cpu_type(MXC_CPU_MX21);
75 mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR));
76
77 iotable_init(imx21_io_desc, ARRAY_SIZE(imx21_io_desc));
78}
79
80int imx21_register_gpios(void);
81
82void __init mx21_init_irq(void)
83{
84 mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
85 imx21_register_gpios();
86}
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
new file mode 100644
index 000000000000..a24622957ff2
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -0,0 +1,86 @@
1/*
2 * arch/arm/mach-imx/mm-imx27.c
3 *
4 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <linux/mm.h>
22#include <linux/init.h>
23#include <mach/hardware.h>
24#include <mach/common.h>
25#include <asm/pgtable.h>
26#include <asm/mach/map.h>
27
28/* MX27 memory map definition */
29static struct map_desc imx27_io_desc[] __initdata = {
30 /*
31 * this fixed mapping covers:
32 * - AIPI1
33 * - AIPI2
34 * - AITC
35 * - ROM Patch
36 * - and some reserved space
37 */
38 {
39 .virtual = MX27_AIPI_BASE_ADDR_VIRT,
40 .pfn = __phys_to_pfn(MX27_AIPI_BASE_ADDR),
41 .length = MX27_AIPI_SIZE,
42 .type = MT_DEVICE
43 },
44 /*
45 * this fixed mapping covers:
46 * - CSI
47 * - ATA
48 */
49 {
50 .virtual = MX27_SAHB1_BASE_ADDR_VIRT,
51 .pfn = __phys_to_pfn(MX27_SAHB1_BASE_ADDR),
52 .length = MX27_SAHB1_SIZE,
53 .type = MT_DEVICE
54 },
55 /*
56 * this fixed mapping covers:
57 * - EMI
58 */
59 {
60 .virtual = MX27_X_MEMC_BASE_ADDR_VIRT,
61 .pfn = __phys_to_pfn(MX27_X_MEMC_BASE_ADDR),
62 .length = MX27_X_MEMC_SIZE,
63 .type = MT_DEVICE
64 },
65};
66
67/*
68 * Initialize the memory map. It is called during the
69 * system startup to create static physical to virtual
70 * memory map for the IO modules.
71 */
72void __init mx27_map_io(void)
73{
74 mxc_set_cpu_type(MXC_CPU_MX27);
75 mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
76
77 iotable_init(imx27_io_desc, ARRAY_SIZE(imx27_io_desc));
78}
79
80int imx27_register_gpios(void);
81
82void __init mx27_init_irq(void)
83{
84 mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
85 imx27_register_gpios();
86}
diff --git a/arch/arm/mach-imx/mx1-camera-fiq-ksym.c b/arch/arm/mach-imx/mx1-camera-fiq-ksym.c
new file mode 100644
index 000000000000..b09ee12a4ff0
--- /dev/null
+++ b/arch/arm/mach-imx/mx1-camera-fiq-ksym.c
@@ -0,0 +1,18 @@
1/*
2 * Exported ksyms of ARCH_MX1
3 *
4 * Copyright (C) 2008, Darius Augulis <augulis.darius@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/module.h>
13
14#include <mach/mx1_camera.h>
15
16/* IMX camera FIQ handler */
17EXPORT_SYMBOL(mx1_camera_sof_fiq_start);
18EXPORT_SYMBOL(mx1_camera_sof_fiq_end);
diff --git a/arch/arm/mach-imx/mx1-camera-fiq.S b/arch/arm/mach-imx/mx1-camera-fiq.S
new file mode 100644
index 000000000000..9c69aa65bf17
--- /dev/null
+++ b/arch/arm/mach-imx/mx1-camera-fiq.S
@@ -0,0 +1,35 @@
1/*
2 * Copyright (C) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
3 *
4 * Based on linux/arch/arm/lib/floppydma.S
5 * Copyright (C) 1995, 1996 Russell King
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/linkage.h>
12#include <asm/assembler.h>
13
14 .text
15 .global mx1_camera_sof_fiq_end
16 .global mx1_camera_sof_fiq_start
17mx1_camera_sof_fiq_start:
18 @ enable dma
19 ldr r12, [r9]
20 orr r12, r12, #0x00000001
21 str r12, [r9]
22 @ unmask DMA interrupt
23 ldr r12, [r8]
24 bic r12, r12, r13
25 str r12, [r8]
26 @ disable SOF interrupt
27 ldr r12, [r10]
28 bic r12, r12, #0x00010000
29 str r12, [r10]
30 @ clear SOF flag
31 mov r12, #0x00010000
32 str r12, [r11]
33 @ return from FIQ
34 subs pc, lr, #4
35mx1_camera_sof_fiq_end:
diff --git a/arch/arm/mach-imx/pcm970-baseboard.c b/arch/arm/mach-imx/pcm970-baseboard.c
new file mode 100644
index 000000000000..f490a406d57e
--- /dev/null
+++ b/arch/arm/mach-imx/pcm970-baseboard.c
@@ -0,0 +1,233 @@
1/*
2 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 * MA 02110-1301, USA.
17 */
18
19#include <linux/gpio.h>
20#include <linux/irq.h>
21#include <linux/platform_device.h>
22#include <linux/can/platform/sja1000.h>
23
24#include <asm/mach/arch.h>
25
26#include <mach/common.h>
27#include <mach/iomux-mx27.h>
28#include <mach/imxfb.h>
29#include <mach/hardware.h>
30#include <mach/mmc.h>
31
32#include "devices.h"
33
34static int pcm970_pins[] = {
35 /* SDHC */
36 PB4_PF_SD2_D0,
37 PB5_PF_SD2_D1,
38 PB6_PF_SD2_D2,
39 PB7_PF_SD2_D3,
40 PB8_PF_SD2_CMD,
41 PB9_PF_SD2_CLK,
42 /* display */
43 PA5_PF_LSCLK,
44 PA6_PF_LD0,
45 PA7_PF_LD1,
46 PA8_PF_LD2,
47 PA9_PF_LD3,
48 PA10_PF_LD4,
49 PA11_PF_LD5,
50 PA12_PF_LD6,
51 PA13_PF_LD7,
52 PA14_PF_LD8,
53 PA15_PF_LD9,
54 PA16_PF_LD10,
55 PA17_PF_LD11,
56 PA18_PF_LD12,
57 PA19_PF_LD13,
58 PA20_PF_LD14,
59 PA21_PF_LD15,
60 PA22_PF_LD16,
61 PA23_PF_LD17,
62 PA24_PF_REV,
63 PA25_PF_CLS,
64 PA26_PF_PS,
65 PA27_PF_SPL_SPR,
66 PA28_PF_HSYNC,
67 PA29_PF_VSYNC,
68 PA30_PF_CONTRAST,
69 PA31_PF_OE_ACD,
70 /*
71 * it seems the data line misses a pullup, so we must enable
72 * the internal pullup as a local workaround
73 */
74 PD17_PF_I2C_DATA | GPIO_PUEN,
75 PD18_PF_I2C_CLK,
76 /* Camera */
77 PB10_PF_CSI_D0,
78 PB11_PF_CSI_D1,
79 PB12_PF_CSI_D2,
80 PB13_PF_CSI_D3,
81 PB14_PF_CSI_D4,
82 PB15_PF_CSI_MCLK,
83 PB16_PF_CSI_PIXCLK,
84 PB17_PF_CSI_D5,
85 PB18_PF_CSI_D6,
86 PB19_PF_CSI_D7,
87 PB20_PF_CSI_VSYNC,
88 PB21_PF_CSI_HSYNC,
89};
90
91static int pcm970_sdhc2_get_ro(struct device *dev)
92{
93 return gpio_get_value(GPIO_PORTC + 28);
94}
95
96static int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void *data)
97{
98 int ret;
99
100 ret = request_irq(IRQ_GPIOC(29), detect_irq, IRQF_TRIGGER_FALLING,
101 "imx-mmc-detect", data);
102 if (ret)
103 return ret;
104
105 ret = gpio_request(GPIO_PORTC + 28, "imx-mmc-ro");
106 if (ret) {
107 free_irq(IRQ_GPIOC(29), data);
108 return ret;
109 }
110
111 gpio_direction_input(GPIO_PORTC + 28);
112
113 return 0;
114}
115
116static void pcm970_sdhc2_exit(struct device *dev, void *data)
117{
118 free_irq(IRQ_GPIOC(29), data);
119 gpio_free(GPIO_PORTC + 28);
120}
121
122static struct imxmmc_platform_data sdhc_pdata = {
123 .get_ro = pcm970_sdhc2_get_ro,
124 .init = pcm970_sdhc2_init,
125 .exit = pcm970_sdhc2_exit,
126};
127
128static struct imx_fb_videomode pcm970_modes[] = {
129 {
130 .mode = {
131 .name = "Sharp-LQ035Q7",
132 .refresh = 60,
133 .xres = 240,
134 .yres = 320,
135 .pixclock = 188679, /* in ps (5.3MHz) */
136 .hsync_len = 7,
137 .left_margin = 5,
138 .right_margin = 16,
139 .vsync_len = 1,
140 .upper_margin = 7,
141 .lower_margin = 9,
142 },
143 /*
144 * - HSYNC active high
145 * - VSYNC active high
146 * - clk notenabled while idle
147 * - clock not inverted
148 * - data not inverted
149 * - data enable low active
150 * - enable sharp mode
151 */
152 .pcr = 0xF00080C0,
153 .bpp = 16,
154 }, {
155 .mode = {
156 .name = "TX090",
157 .refresh = 60,
158 .xres = 240,
159 .yres = 320,
160 .pixclock = 38255,
161 .left_margin = 144,
162 .right_margin = 0,
163 .upper_margin = 7,
164 .lower_margin = 40,
165 .hsync_len = 96,
166 .vsync_len = 1,
167 },
168 /*
169 * - HSYNC active low (1 << 22)
170 * - VSYNC active low (1 << 23)
171 * - clk notenabled while idle
172 * - clock not inverted
173 * - data not inverted
174 * - data enable low active
175 * - enable sharp mode
176 */
177 .pcr = 0xF0008080 | (1<<22) | (1<<23) | (1<<19),
178 .bpp = 32,
179 },
180};
181
182static struct imx_fb_platform_data pcm038_fb_data = {
183 .mode = pcm970_modes,
184 .num_modes = ARRAY_SIZE(pcm970_modes),
185
186 .pwmr = 0x00A903FF,
187 .lscr1 = 0x00120300,
188 .dmacr = 0x00020010,
189};
190
191static struct resource pcm970_sja1000_resources[] = {
192 {
193 .start = MX27_CS4_BASE_ADDR,
194 .end = MX27_CS4_BASE_ADDR + 0x100 - 1,
195 .flags = IORESOURCE_MEM,
196 }, {
197 .start = IRQ_GPIOE(19),
198 .end = IRQ_GPIOE(19),
199 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
200 },
201};
202
203struct sja1000_platform_data pcm970_sja1000_platform_data = {
204 .osc_freq = 16000000,
205 .ocr = OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL,
206 .cdr = CDR_CBP,
207};
208
209static struct platform_device pcm970_sja1000 = {
210 .name = "sja1000_platform",
211 .dev = {
212 .platform_data = &pcm970_sja1000_platform_data,
213 },
214 .resource = pcm970_sja1000_resources,
215 .num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
216};
217
218/*
219 * system init for baseboard usage. Will be called by pcm038 init.
220 *
221 * Add platform devices present on this baseboard and init
222 * them from CPU side as far as required to use them later on
223 */
224void __init pcm970_baseboard_init(void)
225{
226 mxc_gpio_setup_multiple_pins(pcm970_pins, ARRAY_SIZE(pcm970_pins),
227 "PCM970");
228
229 mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
230 mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_IN);
231 mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
232 platform_device_register(&pcm970_sja1000);
233}
diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c
new file mode 100644
index 000000000000..afc17ce0bb54
--- /dev/null
+++ b/arch/arm/mach-imx/pm-imx27.c
@@ -0,0 +1,46 @@
1/*
2 * i.MX27 Power Management Routines
3 *
4 * Based on Freescale's BSP
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License.
8 */
9
10#include <linux/kernel.h>
11#include <linux/suspend.h>
12#include <linux/io.h>
13#include <mach/system.h>
14#include <mach/mx27.h>
15
16static int mx27_suspend_enter(suspend_state_t state)
17{
18 u32 cscr;
19 switch (state) {
20 case PM_SUSPEND_MEM:
21 /* Clear MPEN and SPEN to disable MPLL/SPLL */
22 cscr = __raw_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR));
23 cscr &= 0xFFFFFFFC;
24 __raw_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR));
25 /* Executes WFI */
26 arch_idle();
27 break;
28
29 default:
30 return -EINVAL;
31 }
32 return 0;
33}
34
35static struct platform_suspend_ops mx27_suspend_ops = {
36 .enter = mx27_suspend_enter,
37 .valid = suspend_valid_only_mem,
38};
39
40static int __init mx27_pm_init(void)
41{
42 suspend_set_ops(&mx27_suspend_ops);
43 return 0;
44}
45
46device_initcall(mx27_pm_init);