aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2010-06-10 09:11:13 -0400
committerUwe Kleine-König <u.kleine-koenig@pengutronix.de>2010-06-24 09:40:38 -0400
commitd109167b9c1002770d194644d5580a1f3588f7fc (patch)
tree0cbc6fc238b6ce639080a9bf1971c813534d8777 /arch/arm/mach-imx
parentf1d4cbef18999548ade1007bfb63cc1fa69c385e (diff)
ARM: imx: rename mach dir for mx21 and mx27 to mach-imx
Finally all imx code should end up there, start with mach-mx2. While touching all files rename some files to use a hyphen instead of an underscore. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/Kconfig116
-rw-r--r--arch/arm/mach-imx/Makefile23
-rw-r--r--arch/arm/mach-imx/Makefile.boot7
-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.c503
-rw-r--r--arch/arm/mach-imx/devices.h42
-rw-r--r--arch/arm/mach-imx/eukrea_mbimx27-baseboard.c249
-rw-r--r--arch/arm/mach-imx/mach-cpuimx27.c235
-rw-r--r--arch/arm/mach-imx/mach-imx27lite.c94
-rw-r--r--arch/arm/mach-imx/mach-mx21ads.c328
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c100
-rw-r--r--arch/arm/mach-imx/mach-mx27ads.c373
-rw-r--r--arch/arm/mach-imx/mach-mxt_td60.c295
-rw-r--r--arch/arm/mach-imx/mach-pca100.c396
-rw-r--r--arch/arm/mach-imx/mach-pcm038.c359
-rw-r--r--arch/arm/mach-imx/mm-imx21.c83
-rw-r--r--arch/arm/mach-imx/mm-imx27.c83
-rw-r--r--arch/arm/mach-imx/pcm970-baseboard.c233
-rw-r--r--arch/arm/mach-imx/serial.c141
21 files changed, 5726 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
new file mode 100644
index 000000000000..742fd4e6dcb9
--- /dev/null
+++ b/arch/arm/mach-imx/Kconfig
@@ -0,0 +1,116 @@
1if ARCH_MX2
2
3choice
4 prompt "CPUs:"
5 default MACH_MX21
6
7config MACH_MX21
8 bool "i.MX21 support"
9 select ARCH_MXC_AUDMUX_V1
10 help
11 This enables support for Freescale's MX2 based i.MX21 processor.
12
13config MACH_MX27
14 bool "i.MX27 support"
15 select ARCH_MXC_AUDMUX_V1
16 help
17 This enables support for Freescale's MX2 based i.MX27 processor.
18
19endchoice
20
21comment "MX2 platforms:"
22
23config MACH_MX21ADS
24 bool "MX21ADS platform"
25 depends on MACH_MX21
26 help
27 Include support for MX21ADS platform. This includes specific
28 configurations for the board and its peripherals.
29
30config MACH_MX27ADS
31 bool "MX27ADS platform"
32 depends on MACH_MX27
33 help
34 Include support for MX27ADS platform. This includes specific
35 configurations for the board and its peripherals.
36
37config MACH_PCM038
38 bool "Phytec phyCORE-i.MX27 CPU module (pcm038)"
39 depends on MACH_MX27
40 select MXC_ULPI if USB_ULPI
41 help
42 Include support for phyCORE-i.MX27 (aka pcm038) platform. This
43 includes specific configurations for the module and its peripherals.
44
45choice
46 prompt "Baseboard"
47 depends on MACH_PCM038
48 default MACH_PCM970_BASEBOARD
49
50config MACH_PCM970_BASEBOARD
51 prompt "PHYTEC PCM970 development board"
52 bool
53 help
54 This adds board specific devices that can be found on Phytec's
55 PCM970 evaluation board.
56
57endchoice
58
59config MACH_CPUIMX27
60 bool "Eukrea CPUIMX27 module"
61 depends on MACH_MX27
62 help
63 Include support for Eukrea CPUIMX27 platform. This includes
64 specific configurations for the module and its peripherals.
65
66config MACH_EUKREA_CPUIMX27_USESDHC2
67 bool "CPUIMX27 integrates SDHC2 module"
68 depends on MACH_CPUIMX27
69 help
70 This adds support for the internal SDHC2 used on CPUIMX27 used
71 for wifi or eMMC.
72
73choice
74 prompt "Baseboard"
75 depends on MACH_CPUIMX27
76 default MACH_EUKREA_MBIMX27_BASEBOARD
77
78config MACH_EUKREA_MBIMX27_BASEBOARD
79 prompt "Eukrea MBIMX27 development board"
80 bool
81 help
82 This adds board specific devices that can be found on Eukrea's
83 MBIMX27 evaluation board.
84
85endchoice
86
87config MACH_MX27_3DS
88 bool "MX27PDK platform"
89 depends on MACH_MX27
90 help
91 Include support for MX27PDK platform. This includes specific
92 configurations for the board and its peripherals.
93
94config MACH_IMX27LITE
95 bool "LogicPD MX27 LITEKIT platform"
96 depends on MACH_MX27
97 help
98 Include support for MX27 LITEKIT platform. This includes specific
99 configurations for the board and its peripherals.
100
101config MACH_PCA100
102 bool "Phytec phyCARD-s (pca100)"
103 depends on MACH_MX27
104 select MXC_ULPI if USB_ULPI
105 help
106 Include support for phyCARD-s (aka pca100) platform. This
107 includes specific configurations for the module and its peripherals.
108
109config MACH_MXT_TD60
110 bool "Maxtrack i-MXT TD60"
111 depends on MACH_MX27
112 help
113 Include support for i-MXT (aka td60) platform. This
114 includes specific configurations for the module and its peripherals.
115
116endif
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
new file mode 100644
index 000000000000..068f4937debd
--- /dev/null
+++ b/arch/arm/mach-imx/Makefile
@@ -0,0 +1,23 @@
1#
2# Makefile for the linux kernel.
3#
4
5# Object file lists.
6
7obj-y := devices.o serial.o
8
9obj-$(CONFIG_MACH_MX21) += clock-imx21.o mm-imx21.o
10
11obj-$(CONFIG_MACH_MX27) += cpu-imx27.o
12obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o
13
14obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o
15obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
16obj-$(CONFIG_MACH_PCM038) += mach-pcm038.o
17obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
18obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o
19obj-$(CONFIG_MACH_IMX27LITE) += mach-imx27lite.o
20obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o
21obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
22obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
23obj-$(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..e867398a8fdb
--- /dev/null
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -0,0 +1,7 @@
1zreladdr-$(CONFIG_MACH_MX21) := 0xC0008000
2params_phys-$(CONFIG_MACH_MX21) := 0xC0000100
3initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
4
5zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000
6params_phys-$(CONFIG_MACH_MX27) := 0xA0000100
7initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
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..0f0823c8b170
--- /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(NULL, "csi", 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.c b/arch/arm/mach-imx/devices.c
new file mode 100644
index 000000000000..a0aeb8a4adc1
--- /dev/null
+++ b/arch/arm/mach-imx/devices.c
@@ -0,0 +1,503 @@
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 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27 * MA 02110-1301, USA.
28 */
29#include <linux/module.h>
30#include <linux/kernel.h>
31#include <linux/init.h>
32#include <linux/platform_device.h>
33#include <linux/gpio.h>
34#include <linux/dma-mapping.h>
35
36#include <mach/irqs.h>
37#include <mach/hardware.h>
38#include <mach/common.h>
39#include <mach/mmc.h>
40
41#include "devices.h"
42
43/*
44 * SPI master controller
45 *
46 * - i.MX1: 2 channel (slighly different register setting)
47 * - i.MX21: 2 channel
48 * - i.MX27: 3 channel
49 */
50#define DEFINE_IMX_SPI_DEVICE(n, baseaddr, irq) \
51 static struct resource mxc_spi_resources ## n[] = { \
52 { \
53 .start = baseaddr, \
54 .end = baseaddr + SZ_4K - 1, \
55 .flags = IORESOURCE_MEM, \
56 }, { \
57 .start = irq, \
58 .end = irq, \
59 .flags = IORESOURCE_IRQ, \
60 }, \
61 }; \
62 \
63 struct platform_device mxc_spi_device ## n = { \
64 .name = "spi_imx", \
65 .id = n, \
66 .num_resources = ARRAY_SIZE(mxc_spi_resources ## n), \
67 .resource = mxc_spi_resources ## n, \
68 }
69
70DEFINE_IMX_SPI_DEVICE(0, MX2x_CSPI1_BASE_ADDR, MX2x_INT_CSPI1);
71DEFINE_IMX_SPI_DEVICE(1, MX2x_CSPI2_BASE_ADDR, MX2x_INT_CSPI2);
72
73#ifdef CONFIG_MACH_MX27
74DEFINE_IMX_SPI_DEVICE(2, MX27_CSPI3_BASE_ADDR, MX27_INT_CSPI3);
75#endif
76
77/*
78 * General Purpose Timer
79 * - i.MX21: 3 timers
80 * - i.MX27: 6 timers
81 */
82#define DEFINE_IMX_GPT_DEVICE(n, baseaddr, irq) \
83 static struct resource timer ## n ##_resources[] = { \
84 { \
85 .start = baseaddr, \
86 .end = baseaddr + SZ_4K - 1, \
87 .flags = IORESOURCE_MEM, \
88 }, { \
89 .start = irq, \
90 .end = irq, \
91 .flags = IORESOURCE_IRQ, \
92 } \
93 }; \
94 \
95 struct platform_device mxc_gpt ## n = { \
96 .name = "imx_gpt", \
97 .id = n, \
98 .num_resources = ARRAY_SIZE(timer ## n ## _resources), \
99 .resource = timer ## n ## _resources, \
100 }
101
102/* We use gpt1 as system timer, so do not add a device for this one */
103DEFINE_IMX_GPT_DEVICE(1, MX2x_GPT2_BASE_ADDR, MX2x_INT_GPT2);
104DEFINE_IMX_GPT_DEVICE(2, MX2x_GPT3_BASE_ADDR, MX2x_INT_GPT3);
105
106#ifdef CONFIG_MACH_MX27
107DEFINE_IMX_GPT_DEVICE(3, MX27_GPT4_BASE_ADDR, MX27_INT_GPT4);
108DEFINE_IMX_GPT_DEVICE(4, MX27_GPT5_BASE_ADDR, MX27_INT_GPT5);
109DEFINE_IMX_GPT_DEVICE(5, MX27_GPT6_BASE_ADDR, MX27_INT_GPT6);
110#endif
111
112/* Watchdog: i.MX1 has seperate driver, i.MX21 and i.MX27 are equal */
113static struct resource mxc_wdt_resources[] = {
114 {
115 .start = MX2x_WDOG_BASE_ADDR,
116 .end = MX2x_WDOG_BASE_ADDR + SZ_4K - 1,
117 .flags = IORESOURCE_MEM,
118 },
119};
120
121struct platform_device mxc_wdt = {
122 .name = "imx2-wdt",
123 .id = 0,
124 .num_resources = ARRAY_SIZE(mxc_wdt_resources),
125 .resource = mxc_wdt_resources,
126};
127
128static struct resource mxc_w1_master_resources[] = {
129 {
130 .start = MX2x_OWIRE_BASE_ADDR,
131 .end = MX2x_OWIRE_BASE_ADDR + SZ_4K - 1,
132 .flags = IORESOURCE_MEM,
133 },
134};
135
136struct platform_device mxc_w1_master_device = {
137 .name = "mxc_w1",
138 .id = 0,
139 .num_resources = ARRAY_SIZE(mxc_w1_master_resources),
140 .resource = mxc_w1_master_resources,
141};
142
143#define DEFINE_MXC_NAND_DEVICE(pfx, baseaddr, irq) \
144 static struct resource pfx ## _nand_resources[] = { \
145 { \
146 .start = baseaddr, \
147 .end = baseaddr + SZ_4K - 1, \
148 .flags = IORESOURCE_MEM, \
149 }, { \
150 .start = irq, \
151 .end = irq, \
152 .flags = IORESOURCE_IRQ, \
153 }, \
154 }; \
155 \
156 struct platform_device pfx ## _nand_device = { \
157 .name = "mxc_nand", \
158 .id = 0, \
159 .num_resources = ARRAY_SIZE(pfx ## _nand_resources), \
160 .resource = pfx ## _nand_resources, \
161 }
162
163#ifdef CONFIG_MACH_MX21
164DEFINE_MXC_NAND_DEVICE(imx21, MX21_NFC_BASE_ADDR, MX21_INT_NANDFC);
165#endif
166
167#ifdef CONFIG_MACH_MX27
168DEFINE_MXC_NAND_DEVICE(imx27, MX27_NFC_BASE_ADDR, MX27_INT_NANDFC);
169#endif
170
171/*
172 * lcdc:
173 * - i.MX1: the basic controller
174 * - i.MX21: to be checked
175 * - i.MX27: like i.MX1, with slightly variations
176 */
177static struct resource mxc_fb[] = {
178 {
179 .start = MX2x_LCDC_BASE_ADDR,
180 .end = MX2x_LCDC_BASE_ADDR + SZ_4K - 1,
181 .flags = IORESOURCE_MEM,
182 }, {
183 .start = MX2x_INT_LCDC,
184 .end = MX2x_INT_LCDC,
185 .flags = IORESOURCE_IRQ,
186 }
187};
188
189/* mxc lcd driver */
190struct platform_device mxc_fb_device = {
191 .name = "imx-fb",
192 .id = 0,
193 .num_resources = ARRAY_SIZE(mxc_fb),
194 .resource = mxc_fb,
195 .dev = {
196 .coherent_dma_mask = DMA_BIT_MASK(32),
197 },
198};
199
200#ifdef CONFIG_MACH_MX27
201static struct resource mxc_fec_resources[] = {
202 {
203 .start = MX27_FEC_BASE_ADDR,
204 .end = MX27_FEC_BASE_ADDR + SZ_4K - 1,
205 .flags = IORESOURCE_MEM,
206 }, {
207 .start = MX27_INT_FEC,
208 .end = MX27_INT_FEC,
209 .flags = IORESOURCE_IRQ,
210 },
211};
212
213struct platform_device mxc_fec_device = {
214 .name = "fec",
215 .id = 0,
216 .num_resources = ARRAY_SIZE(mxc_fec_resources),
217 .resource = mxc_fec_resources,
218};
219#endif
220
221#define DEFINE_IMX_I2C_DEVICE(n, baseaddr, irq) \
222 static struct resource mxc_i2c_resources ## n[] = { \
223 { \
224 .start = baseaddr, \
225 .end = baseaddr + SZ_4K - 1, \
226 .flags = IORESOURCE_MEM, \
227 }, { \
228 .start = irq, \
229 .end = irq, \
230 .flags = IORESOURCE_IRQ, \
231 } \
232 }; \
233 \
234 struct platform_device mxc_i2c_device ## n = { \
235 .name = "imx-i2c", \
236 .id = n, \
237 .num_resources = ARRAY_SIZE(mxc_i2c_resources ## n), \
238 .resource = mxc_i2c_resources ## n, \
239 }
240
241DEFINE_IMX_I2C_DEVICE(0, MX2x_I2C_BASE_ADDR, MX2x_INT_I2C);
242
243#ifdef CONFIG_MACH_MX27
244DEFINE_IMX_I2C_DEVICE(1, MX27_I2C2_BASE_ADDR, MX27_INT_I2C2);
245#endif
246
247static struct resource mxc_pwm_resources[] = {
248 {
249 .start = MX2x_PWM_BASE_ADDR,
250 .end = MX2x_PWM_BASE_ADDR + SZ_4K - 1,
251 .flags = IORESOURCE_MEM,
252 }, {
253 .start = MX2x_INT_PWM,
254 .end = MX2x_INT_PWM,
255 .flags = IORESOURCE_IRQ,
256 }
257};
258
259struct platform_device mxc_pwm_device = {
260 .name = "mxc_pwm",
261 .id = 0,
262 .num_resources = ARRAY_SIZE(mxc_pwm_resources),
263 .resource = mxc_pwm_resources,
264};
265
266#define DEFINE_MXC_MMC_DEVICE(n, baseaddr, irq, dmareq) \
267 static struct resource mxc_sdhc_resources ## n[] = { \
268 { \
269 .start = baseaddr, \
270 .end = baseaddr + SZ_4K - 1, \
271 .flags = IORESOURCE_MEM, \
272 }, { \
273 .start = irq, \
274 .end = irq, \
275 .flags = IORESOURCE_IRQ, \
276 }, { \
277 .start = dmareq, \
278 .end = dmareq, \
279 .flags = IORESOURCE_DMA, \
280 }, \
281 }; \
282 \
283 static u64 mxc_sdhc ## n ## _dmamask = DMA_BIT_MASK(32); \
284 \
285 struct platform_device mxc_sdhc_device ## n = { \
286 .name = "mxc-mmc", \
287 .id = n, \
288 .dev = { \
289 .dma_mask = &mxc_sdhc ## n ## _dmamask, \
290 .coherent_dma_mask = DMA_BIT_MASK(32), \
291 }, \
292 .num_resources = ARRAY_SIZE(mxc_sdhc_resources ## n), \
293 .resource = mxc_sdhc_resources ## n, \
294 }
295
296DEFINE_MXC_MMC_DEVICE(0, MX2x_SDHC1_BASE_ADDR, MX2x_INT_SDHC1, MX2x_DMA_REQ_SDHC1);
297DEFINE_MXC_MMC_DEVICE(1, MX2x_SDHC2_BASE_ADDR, MX2x_INT_SDHC2, MX2x_DMA_REQ_SDHC2);
298
299#ifdef CONFIG_MACH_MX27
300static struct resource otg_resources[] = {
301 {
302 .start = MX27_USBOTG_BASE_ADDR,
303 .end = MX27_USBOTG_BASE_ADDR + 0x1ff,
304 .flags = IORESOURCE_MEM,
305 }, {
306 .start = MX27_INT_USB3,
307 .end = MX27_INT_USB3,
308 .flags = IORESOURCE_IRQ,
309 },
310};
311
312static u64 otg_dmamask = DMA_BIT_MASK(32);
313
314/* OTG gadget device */
315struct platform_device mxc_otg_udc_device = {
316 .name = "fsl-usb2-udc",
317 .id = -1,
318 .dev = {
319 .dma_mask = &otg_dmamask,
320 .coherent_dma_mask = DMA_BIT_MASK(32),
321 },
322 .resource = otg_resources,
323 .num_resources = ARRAY_SIZE(otg_resources),
324};
325
326/* OTG host */
327struct platform_device mxc_otg_host = {
328 .name = "mxc-ehci",
329 .id = 0,
330 .dev = {
331 .coherent_dma_mask = DMA_BIT_MASK(32),
332 .dma_mask = &otg_dmamask,
333 },
334 .resource = otg_resources,
335 .num_resources = ARRAY_SIZE(otg_resources),
336};
337
338/* USB host 1 */
339
340static u64 usbh1_dmamask = DMA_BIT_MASK(32);
341
342static struct resource mxc_usbh1_resources[] = {
343 {
344 .start = MX27_USBOTG_BASE_ADDR + 0x200,
345 .end = MX27_USBOTG_BASE_ADDR + 0x3ff,
346 .flags = IORESOURCE_MEM,
347 }, {
348 .start = MX27_INT_USB1,
349 .end = MX27_INT_USB1,
350 .flags = IORESOURCE_IRQ,
351 },
352};
353
354struct platform_device mxc_usbh1 = {
355 .name = "mxc-ehci",
356 .id = 1,
357 .dev = {
358 .coherent_dma_mask = DMA_BIT_MASK(32),
359 .dma_mask = &usbh1_dmamask,
360 },
361 .resource = mxc_usbh1_resources,
362 .num_resources = ARRAY_SIZE(mxc_usbh1_resources),
363};
364
365/* USB host 2 */
366static u64 usbh2_dmamask = DMA_BIT_MASK(32);
367
368static struct resource mxc_usbh2_resources[] = {
369 {
370 .start = MX27_USBOTG_BASE_ADDR + 0x400,
371 .end = MX27_USBOTG_BASE_ADDR + 0x5ff,
372 .flags = IORESOURCE_MEM,
373 }, {
374 .start = MX27_INT_USB2,
375 .end = MX27_INT_USB2,
376 .flags = IORESOURCE_IRQ,
377 },
378};
379
380struct platform_device mxc_usbh2 = {
381 .name = "mxc-ehci",
382 .id = 2,
383 .dev = {
384 .coherent_dma_mask = DMA_BIT_MASK(32),
385 .dma_mask = &usbh2_dmamask,
386 },
387 .resource = mxc_usbh2_resources,
388 .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
389};
390#endif
391
392#define DEFINE_IMX_SSI_DMARES(_name, ssin, suffix) \
393 { \
394 .name = _name, \
395 .start = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
396 .end = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
397 .flags = IORESOURCE_DMA, \
398 }
399
400#define DEFINE_IMX_SSI_DEVICE(n, ssin, baseaddr, irq) \
401 static struct resource imx_ssi_resources ## n[] = { \
402 { \
403 .start = MX2x_SSI ## ssin ## _BASE_ADDR, \
404 .end = MX2x_SSI ## ssin ## _BASE_ADDR + 0x6f, \
405 .flags = IORESOURCE_MEM, \
406 }, { \
407 .start = MX2x_INT_SSI1, \
408 .end = MX2x_INT_SSI1, \
409 .flags = IORESOURCE_IRQ, \
410 }, \
411 DEFINE_IMX_SSI_DMARES("tx0", ssin, TX0), \
412 DEFINE_IMX_SSI_DMARES("rx0", ssin, RX0), \
413 DEFINE_IMX_SSI_DMARES("tx1", ssin, TX1), \
414 DEFINE_IMX_SSI_DMARES("rx1", ssin, RX1), \
415 }; \
416 \
417 struct platform_device imx_ssi_device ## n = { \
418 .name = "imx-ssi", \
419 .id = n, \
420 .num_resources = ARRAY_SIZE(imx_ssi_resources ## n), \
421 .resource = imx_ssi_resources ## n, \
422 }
423
424DEFINE_IMX_SSI_DEVICE(0, 1, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
425DEFINE_IMX_SSI_DEVICE(1, 2, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
426
427/* GPIO port description */
428#define DEFINE_MXC_GPIO_PORT_IRQ(SOC, n, _irq) \
429 { \
430 .chip.label = "gpio-" #n, \
431 .irq = _irq, \
432 .base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR + \
433 n * 0x100), \
434 .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \
435 }
436
437#define DEFINE_MXC_GPIO_PORT(SOC, n) \
438 { \
439 .chip.label = "gpio-" #n, \
440 .base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR + \
441 n * 0x100), \
442 .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \
443 }
444
445#define DEFINE_MXC_GPIO_PORTS(SOC, pfx) \
446 static struct mxc_gpio_port pfx ## _gpio_ports[] = { \
447 DEFINE_MXC_GPIO_PORT_IRQ(SOC, 0, SOC ## _INT_GPIO), \
448 DEFINE_MXC_GPIO_PORT(SOC, 1), \
449 DEFINE_MXC_GPIO_PORT(SOC, 2), \
450 DEFINE_MXC_GPIO_PORT(SOC, 3), \
451 DEFINE_MXC_GPIO_PORT(SOC, 4), \
452 DEFINE_MXC_GPIO_PORT(SOC, 5), \
453 }
454
455#ifdef CONFIG_MACH_MX21
456DEFINE_MXC_GPIO_PORTS(MX21, imx21);
457#endif
458
459#ifdef CONFIG_MACH_MX27
460DEFINE_MXC_GPIO_PORTS(MX27, imx27);
461#endif
462
463int __init mxc_register_gpios(void)
464{
465#ifdef CONFIG_MACH_MX21
466 if (cpu_is_mx21())
467 return mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports));
468 else
469#endif
470#ifdef CONFIG_MACH_MX27
471 if (cpu_is_mx27())
472 return mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports));
473 else
474#endif
475 return 0;
476}
477
478#ifdef CONFIG_MACH_MX21
479static struct resource mx21_usbhc_resources[] = {
480 {
481 .start = MX21_USBOTG_BASE_ADDR,
482 .end = MX21_USBOTG_BASE_ADDR + SZ_8K - 1,
483 .flags = IORESOURCE_MEM,
484 },
485 {
486 .start = MX21_INT_USBHOST,
487 .end = MX21_INT_USBHOST,
488 .flags = IORESOURCE_IRQ,
489 },
490};
491
492struct platform_device mx21_usbhc_device = {
493 .name = "imx21-hcd",
494 .id = 0,
495 .dev = {
496 .dma_mask = &mx21_usbhc_device.dev.coherent_dma_mask,
497 .coherent_dma_mask = DMA_BIT_MASK(32),
498 },
499 .num_resources = ARRAY_SIZE(mx21_usbhc_resources),
500 .resource = mx21_usbhc_resources,
501};
502#endif
503
diff --git a/arch/arm/mach-imx/devices.h b/arch/arm/mach-imx/devices.h
new file mode 100644
index 000000000000..84ed51380174
--- /dev/null
+++ b/arch/arm/mach-imx/devices.h
@@ -0,0 +1,42 @@
1extern struct platform_device mxc_gpt1;
2extern struct platform_device mxc_gpt2;
3#ifdef CONFIG_MACH_MX27
4extern struct platform_device mxc_gpt3;
5extern struct platform_device mxc_gpt4;
6extern struct platform_device mxc_gpt5;
7#endif
8extern struct platform_device mxc_wdt;
9extern struct platform_device mxc_uart_device0;
10extern struct platform_device mxc_uart_device1;
11extern struct platform_device mxc_uart_device2;
12extern struct platform_device mxc_uart_device3;
13extern struct platform_device mxc_uart_device4;
14extern struct platform_device mxc_uart_device5;
15extern struct platform_device mxc_w1_master_device;
16#ifdef CONFIG_MACH_MX21
17extern struct platform_device imx21_nand_device;
18#endif
19#ifdef CONFIG_MACH_MX27
20extern struct platform_device imx27_nand_device;
21#endif
22extern struct platform_device mxc_fb_device;
23extern struct platform_device mxc_fec_device;
24extern struct platform_device mxc_pwm_device;
25extern struct platform_device mxc_i2c_device0;
26#ifdef CONFIG_MACH_MX27
27extern struct platform_device mxc_i2c_device1;
28#endif
29extern struct platform_device mxc_sdhc_device0;
30extern struct platform_device mxc_sdhc_device1;
31extern struct platform_device mxc_otg_udc_device;
32extern struct platform_device mxc_otg_host;
33extern struct platform_device mxc_usbh1;
34extern struct platform_device mxc_usbh2;
35extern struct platform_device mxc_spi_device0;
36extern struct platform_device mxc_spi_device1;
37#ifdef CONFIG_MACH_MX27
38extern struct platform_device mxc_spi_device2;
39#endif
40extern struct platform_device mx21_usbhc_device;
41extern struct platform_device imx_ssi_device0;
42extern struct platform_device imx_ssi_device1;
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..f3b169d5245f
--- /dev/null
+++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
@@ -0,0 +1,249 @@
1/*
2 * Copyright (C) 2009 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
28#include <asm/mach/arch.h>
29
30#include <mach/common.h>
31#include <mach/iomux-mx27.h>
32#include <mach/imxfb.h>
33#include <mach/hardware.h>
34#include <mach/mmc.h>
35#include <mach/imx-uart.h>
36
37#include "devices.h"
38
39static int eukrea_mbimx27_pins[] = {
40 /* UART2 */
41 PE3_PF_UART2_CTS,
42 PE4_PF_UART2_RTS,
43 PE6_PF_UART2_TXD,
44 PE7_PF_UART2_RXD,
45 /* UART3 */
46 PE8_PF_UART3_TXD,
47 PE9_PF_UART3_RXD,
48 PE10_PF_UART3_CTS,
49 PE11_PF_UART3_RTS,
50 /* UART4 */
51 PB26_AF_UART4_RTS,
52 PB28_AF_UART4_TXD,
53 PB29_AF_UART4_CTS,
54 PB31_AF_UART4_RXD,
55 /* SDHC1*/
56 PE18_PF_SD1_D0,
57 PE19_PF_SD1_D1,
58 PE20_PF_SD1_D2,
59 PE21_PF_SD1_D3,
60 PE22_PF_SD1_CMD,
61 PE23_PF_SD1_CLK,
62 /* display */
63 PA5_PF_LSCLK,
64 PA6_PF_LD0,
65 PA7_PF_LD1,
66 PA8_PF_LD2,
67 PA9_PF_LD3,
68 PA10_PF_LD4,
69 PA11_PF_LD5,
70 PA12_PF_LD6,
71 PA13_PF_LD7,
72 PA14_PF_LD8,
73 PA15_PF_LD9,
74 PA16_PF_LD10,
75 PA17_PF_LD11,
76 PA18_PF_LD12,
77 PA19_PF_LD13,
78 PA20_PF_LD14,
79 PA21_PF_LD15,
80 PA22_PF_LD16,
81 PA23_PF_LD17,
82 PA28_PF_HSYNC,
83 PA29_PF_VSYNC,
84 PA30_PF_CONTRAST,
85 PA31_PF_OE_ACD,
86 /* SPI1 */
87 PD28_PF_CSPI1_SS0,
88 PD29_PF_CSPI1_SCLK,
89 PD30_PF_CSPI1_MISO,
90 PD31_PF_CSPI1_MOSI,
91};
92
93static struct gpio_led gpio_leds[] = {
94 {
95 .name = "led1",
96 .default_trigger = "heartbeat",
97 .active_low = 1,
98 .gpio = GPIO_PORTF | 16,
99 },
100 {
101 .name = "led2",
102 .default_trigger = "none",
103 .active_low = 1,
104 .gpio = GPIO_PORTF | 19,
105 },
106 {
107 .name = "backlight",
108 .default_trigger = "backlight",
109 .active_low = 0,
110 .gpio = GPIO_PORTE | 5,
111 },
112};
113
114static struct gpio_led_platform_data gpio_led_info = {
115 .leds = gpio_leds,
116 .num_leds = ARRAY_SIZE(gpio_leds),
117};
118
119static struct platform_device leds_gpio = {
120 .name = "leds-gpio",
121 .id = -1,
122 .dev = {
123 .platform_data = &gpio_led_info,
124 },
125};
126
127static struct imx_fb_videomode eukrea_mbimx27_modes[] = {
128 {
129 .mode = {
130 .name = "CMO-QGVA",
131 .refresh = 60,
132 .xres = 320,
133 .yres = 240,
134 .pixclock = 156000,
135 .hsync_len = 30,
136 .left_margin = 38,
137 .right_margin = 20,
138 .vsync_len = 3,
139 .upper_margin = 15,
140 .lower_margin = 4,
141 },
142 .pcr = 0xFAD08B80,
143 .bpp = 16,
144 },
145};
146
147static struct imx_fb_platform_data eukrea_mbimx27_fb_data = {
148 .mode = eukrea_mbimx27_modes,
149 .num_modes = ARRAY_SIZE(eukrea_mbimx27_modes),
150
151 .pwmr = 0x00A903FF,
152 .lscr1 = 0x00120300,
153 .dmacr = 0x00040060,
154};
155
156static struct imxuart_platform_data uart_pdata[] = {
157 {
158 .flags = IMXUART_HAVE_RTSCTS,
159 },
160 {
161 .flags = IMXUART_HAVE_RTSCTS,
162 },
163};
164
165#if defined(CONFIG_TOUCHSCREEN_ADS7846)
166 || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
167
168#define ADS7846_PENDOWN (GPIO_PORTD | 25)
169
170static void ads7846_dev_init(void)
171{
172 if (gpio_request(ADS7846_PENDOWN, "ADS7846 pendown") < 0) {
173 printk(KERN_ERR "can't get ads746 pen down GPIO\n");
174 return;
175 }
176
177 gpio_direction_input(ADS7846_PENDOWN);
178}
179
180static int ads7846_get_pendown_state(void)
181{
182 return !gpio_get_value(ADS7846_PENDOWN);
183}
184
185static struct ads7846_platform_data ads7846_config __initdata = {
186 .get_pendown_state = ads7846_get_pendown_state,
187 .keep_vref_on = 1,
188};
189
190static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = {
191 [0] = {
192 .modalias = "ads7846",
193 .bus_num = 0,
194 .chip_select = 0,
195 .max_speed_hz = 1500000,
196 .irq = IRQ_GPIOD(25),
197 .platform_data = &ads7846_config,
198 .mode = SPI_MODE_2,
199 },
200};
201
202static int eukrea_mbimx27_spi_cs[] = {GPIO_PORTD | 28};
203
204static struct spi_imx_master eukrea_mbimx27_spi_0_data = {
205 .chipselect = eukrea_mbimx27_spi_cs,
206 .num_chipselect = ARRAY_SIZE(eukrea_mbimx27_spi_cs),
207};
208#endif
209
210static struct platform_device *platform_devices[] __initdata = {
211 &leds_gpio,
212};
213
214/*
215 * system init for baseboard usage. Will be called by cpuimx27 init.
216 *
217 * Add platform devices present on this baseboard and init
218 * them from CPU side as far as required to use them later on
219 */
220void __init eukrea_mbimx27_baseboard_init(void)
221{
222 mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins,
223 ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27");
224
225 mxc_register_device(&mxc_uart_device1, &uart_pdata[0]);
226 mxc_register_device(&mxc_uart_device2, &uart_pdata[1]);
227
228 mxc_register_device(&mxc_fb_device, &eukrea_mbimx27_fb_data);
229 mxc_register_device(&mxc_sdhc_device0, NULL);
230
231#if defined(CONFIG_TOUCHSCREEN_ADS7846)
232 || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
233 /* SPI and ADS7846 Touchscreen controler init */
234 mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
235 mxc_gpio_mode(GPIO_PORTD | 25 | GPIO_GPIO | GPIO_IN);
236 mxc_register_device(&mxc_spi_device0, &eukrea_mbimx27_spi_0_data);
237 spi_register_board_info(eukrea_mbimx27_spi_board_info,
238 ARRAY_SIZE(eukrea_mbimx27_spi_board_info));
239 ads7846_dev_init();
240#endif
241
242 /* Leds configuration */
243 mxc_gpio_mode(GPIO_PORTF | 16 | GPIO_GPIO | GPIO_OUT);
244 mxc_gpio_mode(GPIO_PORTF | 19 | GPIO_GPIO | GPIO_OUT);
245 /* Backlight */
246 mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_OUT);
247
248 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
249}
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c
new file mode 100644
index 000000000000..1f616dcaabc9
--- /dev/null
+++ b/arch/arm/mach-imx/mach-cpuimx27.c
@@ -0,0 +1,235 @@
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
30#include <asm/mach-types.h>
31#include <asm/mach/arch.h>
32#include <asm/mach/time.h>
33#include <asm/mach/map.h>
34
35#include <mach/board-eukrea_cpuimx27.h>
36#include <mach/common.h>
37#include <mach/hardware.h>
38#include <mach/i2c.h>
39#include <mach/iomux-mx27.h>
40#include <mach/imx-uart.h>
41#include <mach/mxc_nand.h>
42
43#include "devices.h"
44
45static int eukrea_cpuimx27_pins[] = {
46 /* UART1 */
47 PE12_PF_UART1_TXD,
48 PE13_PF_UART1_RXD,
49 PE14_PF_UART1_CTS,
50 PE15_PF_UART1_RTS,
51 /* UART4 */
52 PB26_AF_UART4_RTS,
53 PB28_AF_UART4_TXD,
54 PB29_AF_UART4_CTS,
55 PB31_AF_UART4_RXD,
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 /* SDHC2 */
79 PB4_PF_SD2_D0,
80 PB5_PF_SD2_D1,
81 PB6_PF_SD2_D2,
82 PB7_PF_SD2_D3,
83 PB8_PF_SD2_CMD,
84 PB9_PF_SD2_CLK,
85#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
86 /* Quad UART's IRQ */
87 GPIO_PORTD | 22 | GPIO_GPIO | GPIO_IN,
88 GPIO_PORTD | 23 | GPIO_GPIO | GPIO_IN,
89 GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN,
90 GPIO_PORTD | 30 | GPIO_GPIO | GPIO_IN,
91#endif
92};
93
94static struct physmap_flash_data eukrea_cpuimx27_flash_data = {
95 .width = 2,
96};
97
98static struct resource eukrea_cpuimx27_flash_resource = {
99 .start = 0xc0000000,
100 .end = 0xc3ffffff,
101 .flags = IORESOURCE_MEM,
102};
103
104static struct platform_device eukrea_cpuimx27_nor_mtd_device = {
105 .name = "physmap-flash",
106 .id = 0,
107 .dev = {
108 .platform_data = &eukrea_cpuimx27_flash_data,
109 },
110 .num_resources = 1,
111 .resource = &eukrea_cpuimx27_flash_resource,
112};
113
114static struct imxuart_platform_data uart_pdata[] = {
115 {
116 .flags = IMXUART_HAVE_RTSCTS,
117 }, {
118 .flags = IMXUART_HAVE_RTSCTS,
119 },
120};
121
122static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = {
123 .width = 1,
124 .hw_ecc = 1,
125};
126
127static struct platform_device *platform_devices[] __initdata = {
128 &eukrea_cpuimx27_nor_mtd_device,
129 &mxc_fec_device,
130};
131
132static struct imxi2c_platform_data eukrea_cpuimx27_i2c_1_data = {
133 .bitrate = 100000,
134};
135
136static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = {
137 {
138 I2C_BOARD_INFO("pcf8563", 0x51),
139 },
140};
141
142#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
143static struct plat_serial8250_port serial_platform_data[] = {
144 {
145 .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x200000),
146 .irq = IRQ_GPIOB(23),
147 .uartclk = 14745600,
148 .regshift = 1,
149 .iotype = UPIO_MEM,
150 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
151 }, {
152 .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x400000),
153 .irq = IRQ_GPIOB(22),
154 .uartclk = 14745600,
155 .regshift = 1,
156 .iotype = UPIO_MEM,
157 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
158 }, {
159 .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x800000),
160 .irq = IRQ_GPIOB(27),
161 .uartclk = 14745600,
162 .regshift = 1,
163 .iotype = UPIO_MEM,
164 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
165 }, {
166 .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x1000000),
167 .irq = IRQ_GPIOB(30),
168 .uartclk = 14745600,
169 .regshift = 1,
170 .iotype = UPIO_MEM,
171 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
172 }, {
173 }
174};
175
176static struct platform_device serial_device = {
177 .name = "serial8250",
178 .id = 0,
179 .dev = {
180 .platform_data = serial_platform_data,
181 },
182};
183#endif
184
185static void __init eukrea_cpuimx27_init(void)
186{
187 mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins,
188 ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27");
189
190 mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
191
192 mxc_register_device(&imx27_nand_device,
193 &eukrea_cpuimx27_nand_board_info);
194
195 i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices,
196 ARRAY_SIZE(eukrea_cpuimx27_i2c_devices));
197
198 mxc_register_device(&mxc_i2c_device0, &eukrea_cpuimx27_i2c_1_data);
199
200 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
201
202#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
203 /* SDHC2 can be used for Wifi */
204 mxc_register_device(&mxc_sdhc_device1, NULL);
205 /* in which case UART4 is also used for Bluetooth */
206 mxc_register_device(&mxc_uart_device3, &uart_pdata[1]);
207#endif
208
209#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
210 platform_device_register(&serial_device);
211#endif
212
213#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD
214 eukrea_mbimx27_baseboard_init();
215#endif
216}
217
218static void __init eukrea_cpuimx27_timer_init(void)
219{
220 mx27_clocks_init(26000000);
221}
222
223static struct sys_timer eukrea_cpuimx27_timer = {
224 .init = eukrea_cpuimx27_timer_init,
225};
226
227MACHINE_START(CPUIMX27, "EUKREA CPUIMX27")
228 .phys_io = MX27_AIPI_BASE_ADDR,
229 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
230 .boot_params = MX27_PHYS_OFFSET + 0x100,
231 .map_io = mx27_map_io,
232 .init_irq = mx27_init_irq,
233 .init_machine = eukrea_cpuimx27_init,
234 .timer = &eukrea_cpuimx27_timer,
235MACHINE_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..fd1dddb8cad5
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx27lite.c
@@ -0,0 +1,94 @@
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 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/platform_device.h>
22#include <linux/gpio.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/hardware.h>
28#include <mach/common.h>
29#include <mach/imx-uart.h>
30#include <mach/iomux-mx27.h>
31
32#include "devices.h"
33
34static unsigned int mx27lite_pins[] = {
35 /* UART1 */
36 PE12_PF_UART1_TXD,
37 PE13_PF_UART1_RXD,
38 PE14_PF_UART1_CTS,
39 PE15_PF_UART1_RTS,
40 /* FEC */
41 PD0_AIN_FEC_TXD0,
42 PD1_AIN_FEC_TXD1,
43 PD2_AIN_FEC_TXD2,
44 PD3_AIN_FEC_TXD3,
45 PD4_AOUT_FEC_RX_ER,
46 PD5_AOUT_FEC_RXD1,
47 PD6_AOUT_FEC_RXD2,
48 PD7_AOUT_FEC_RXD3,
49 PD8_AF_FEC_MDIO,
50 PD9_AIN_FEC_MDC,
51 PD10_AOUT_FEC_CRS,
52 PD11_AOUT_FEC_TX_CLK,
53 PD12_AOUT_FEC_RXD0,
54 PD13_AOUT_FEC_RX_DV,
55 PD14_AOUT_FEC_RX_CLK,
56 PD15_AOUT_FEC_COL,
57 PD16_AIN_FEC_TX_ER,
58 PF23_AIN_FEC_TX_EN,
59};
60
61static struct imxuart_platform_data uart_pdata = {
62 .flags = IMXUART_HAVE_RTSCTS,
63};
64
65static struct platform_device *platform_devices[] __initdata = {
66 &mxc_fec_device,
67};
68
69static void __init mx27lite_init(void)
70{
71 mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
72 "imx27lite");
73 mxc_register_device(&mxc_uart_device0, &uart_pdata);
74 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
75}
76
77static void __init mx27lite_timer_init(void)
78{
79 mx27_clocks_init(26000000);
80}
81
82static struct sys_timer mx27lite_timer = {
83 .init = mx27lite_timer_init,
84};
85
86MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE")
87 .phys_io = MX27_AIPI_BASE_ADDR,
88 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
89 .boot_params = MX27_PHYS_OFFSET + 0x100,
90 .map_io = mx27_map_io,
91 .init_irq = mx27_init_irq,
92 .init_machine = mx27lite_init,
93 .timer = &mx27lite_timer,
94MACHINE_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..99f2492991b4
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -0,0 +1,328 @@
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 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/platform_device.h>
22#include <linux/mtd/mtd.h>
23#include <linux/mtd/physmap.h>
24#include <linux/gpio.h>
25#include <mach/common.h>
26#include <mach/hardware.h>
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/mach/time.h>
30#include <asm/mach/map.h>
31#include <mach/imx-uart.h>
32#include <mach/imxfb.h>
33#include <mach/iomux-mx21.h>
34#include <mach/mxc_nand.h>
35#include <mach/mmc.h>
36
37#include "devices.h"
38
39/*
40 * Memory-mapped I/O on MX21ADS base board
41 */
42#define MX21ADS_MMIO_BASE_ADDR 0xf5000000
43#define MX21ADS_MMIO_SIZE SZ_16M
44
45#define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \
46 (MX21ADS_MMIO_BASE_ADDR + (offset))
47
48#define MX21ADS_CS8900A_IRQ IRQ_GPIOE(11)
49#define MX21ADS_CS8900A_IOBASE_REG MX21ADS_REG_ADDR(0x000000)
50#define MX21ADS_ST16C255_IOBASE_REG MX21ADS_REG_ADDR(0x200000)
51#define MX21ADS_VERSION_REG MX21ADS_REG_ADDR(0x400000)
52#define MX21ADS_IO_REG MX21ADS_REG_ADDR(0x800000)
53
54/* MX21ADS_IO_REG bit definitions */
55#define MX21ADS_IO_SD_WP 0x0001 /* read */
56#define MX21ADS_IO_TP6 0x0001 /* write */
57#define MX21ADS_IO_SW_SEL 0x0002 /* read */
58#define MX21ADS_IO_TP7 0x0002 /* write */
59#define MX21ADS_IO_RESET_E_UART 0x0004
60#define MX21ADS_IO_RESET_BASE 0x0008
61#define MX21ADS_IO_CSI_CTL2 0x0010
62#define MX21ADS_IO_CSI_CTL1 0x0020
63#define MX21ADS_IO_CSI_CTL0 0x0040
64#define MX21ADS_IO_UART1_EN 0x0080
65#define MX21ADS_IO_UART4_EN 0x0100
66#define MX21ADS_IO_LCDON 0x0200
67#define MX21ADS_IO_IRDA_EN 0x0400
68#define MX21ADS_IO_IRDA_FIR_SEL 0x0800
69#define MX21ADS_IO_IRDA_MD0_B 0x1000
70#define MX21ADS_IO_IRDA_MD1 0x2000
71#define MX21ADS_IO_LED4_ON 0x4000
72#define MX21ADS_IO_LED3_ON 0x8000
73
74static unsigned int mx21ads_pins[] = {
75
76 /* CS8900A */
77 (GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11),
78
79 /* UART1 */
80 PE12_PF_UART1_TXD,
81 PE13_PF_UART1_RXD,
82 PE14_PF_UART1_CTS,
83 PE15_PF_UART1_RTS,
84
85 /* UART3 (IrDA) - only TXD and RXD */
86 PE8_PF_UART3_TXD,
87 PE9_PF_UART3_RXD,
88
89 /* UART4 */
90 PB26_AF_UART4_RTS,
91 PB28_AF_UART4_TXD,
92 PB29_AF_UART4_CTS,
93 PB31_AF_UART4_RXD,
94
95 /* LCDC */
96 PA5_PF_LSCLK,
97 PA6_PF_LD0,
98 PA7_PF_LD1,
99 PA8_PF_LD2,
100 PA9_PF_LD3,
101 PA10_PF_LD4,
102 PA11_PF_LD5,
103 PA12_PF_LD6,
104 PA13_PF_LD7,
105 PA14_PF_LD8,
106 PA15_PF_LD9,
107 PA16_PF_LD10,
108 PA17_PF_LD11,
109 PA18_PF_LD12,
110 PA19_PF_LD13,
111 PA20_PF_LD14,
112 PA21_PF_LD15,
113 PA22_PF_LD16,
114 PA24_PF_REV, /* Sharp panel dedicated signal */
115 PA25_PF_CLS, /* Sharp panel dedicated signal */
116 PA26_PF_PS, /* Sharp panel dedicated signal */
117 PA27_PF_SPL_SPR, /* Sharp panel dedicated signal */
118 PA28_PF_HSYNC,
119 PA29_PF_VSYNC,
120 PA30_PF_CONTRAST,
121 PA31_PF_OE_ACD,
122
123 /* MMC/SDHC */
124 PE18_PF_SD1_D0,
125 PE19_PF_SD1_D1,
126 PE20_PF_SD1_D2,
127 PE21_PF_SD1_D3,
128 PE22_PF_SD1_CMD,
129 PE23_PF_SD1_CLK,
130
131 /* NFC */
132 PF0_PF_NRFB,
133 PF1_PF_NFCE,
134 PF2_PF_NFWP,
135 PF3_PF_NFCLE,
136 PF4_PF_NFALE,
137 PF5_PF_NFRE,
138 PF6_PF_NFWE,
139 PF7_PF_NFIO0,
140 PF8_PF_NFIO1,
141 PF9_PF_NFIO2,
142 PF10_PF_NFIO3,
143 PF11_PF_NFIO4,
144 PF12_PF_NFIO5,
145 PF13_PF_NFIO6,
146 PF14_PF_NFIO7,
147};
148
149/* ADS's NOR flash: 2x AM29BDS128HE9VKI on 32-bit bus */
150static struct physmap_flash_data mx21ads_flash_data = {
151 .width = 4,
152};
153
154static struct resource mx21ads_flash_resource = {
155 .start = MX21_CS0_BASE_ADDR,
156 .end = MX21_CS0_BASE_ADDR + 0x02000000 - 1,
157 .flags = IORESOURCE_MEM,
158};
159
160static struct platform_device mx21ads_nor_mtd_device = {
161 .name = "physmap-flash",
162 .id = 0,
163 .dev = {
164 .platform_data = &mx21ads_flash_data,
165 },
166 .num_resources = 1,
167 .resource = &mx21ads_flash_resource,
168};
169
170static struct imxuart_platform_data uart_pdata = {
171 .flags = IMXUART_HAVE_RTSCTS,
172};
173
174static struct imxuart_platform_data uart_norts_pdata = {
175};
176
177
178static int mx21ads_fb_init(struct platform_device *pdev)
179{
180 u16 tmp;
181
182 tmp = __raw_readw(MX21ADS_IO_REG);
183 tmp |= MX21ADS_IO_LCDON;
184 __raw_writew(tmp, MX21ADS_IO_REG);
185 return 0;
186}
187
188static void mx21ads_fb_exit(struct platform_device *pdev)
189{
190 u16 tmp;
191
192 tmp = __raw_readw(MX21ADS_IO_REG);
193 tmp &= ~MX21ADS_IO_LCDON;
194 __raw_writew(tmp, MX21ADS_IO_REG);
195}
196
197/*
198 * Connected is a portrait Sharp-QVGA display
199 * of type: LQ035Q7DB02
200 */
201static struct imx_fb_videomode mx21ads_modes[] = {
202 {
203 .mode = {
204 .name = "Sharp-LQ035Q7",
205 .refresh = 60,
206 .xres = 240,
207 .yres = 320,
208 .pixclock = 188679, /* in ps (5.3MHz) */
209 .hsync_len = 2,
210 .left_margin = 6,
211 .right_margin = 16,
212 .vsync_len = 1,
213 .upper_margin = 8,
214 .lower_margin = 10,
215 },
216 .pcr = 0xfb108bc7,
217 .bpp = 16,
218 },
219};
220
221static struct imx_fb_platform_data mx21ads_fb_data = {
222 .mode = mx21ads_modes,
223 .num_modes = ARRAY_SIZE(mx21ads_modes),
224
225 .pwmr = 0x00a903ff,
226 .lscr1 = 0x00120300,
227 .dmacr = 0x00020008,
228
229 .init = mx21ads_fb_init,
230 .exit = mx21ads_fb_exit,
231};
232
233static int mx21ads_sdhc_get_ro(struct device *dev)
234{
235 return (__raw_readw(MX21ADS_IO_REG) & MX21ADS_IO_SD_WP) ? 1 : 0;
236}
237
238static int mx21ads_sdhc_init(struct device *dev, irq_handler_t detect_irq,
239 void *data)
240{
241 int ret;
242
243 ret = request_irq(IRQ_GPIOD(25), detect_irq,
244 IRQF_TRIGGER_FALLING, "mmc-detect", data);
245 if (ret)
246 goto out;
247 return 0;
248out:
249 return ret;
250}
251
252static void mx21ads_sdhc_exit(struct device *dev, void *data)
253{
254 free_irq(IRQ_GPIOD(25), data);
255}
256
257static struct imxmmc_platform_data mx21ads_sdhc_pdata = {
258 .ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, /* 3.0V */
259 .get_ro = mx21ads_sdhc_get_ro,
260 .init = mx21ads_sdhc_init,
261 .exit = mx21ads_sdhc_exit,
262};
263
264static struct mxc_nand_platform_data mx21ads_nand_board_info = {
265 .width = 1,
266 .hw_ecc = 1,
267};
268
269static struct map_desc mx21ads_io_desc[] __initdata = {
270 /*
271 * Memory-mapped I/O on MX21ADS Base board:
272 * - CS8900A Ethernet controller
273 * - ST16C2552CJ UART
274 * - CPU and Base board version
275 * - Base board I/O register
276 */
277 {
278 .virtual = MX21ADS_MMIO_BASE_ADDR,
279 .pfn = __phys_to_pfn(MX21_CS1_BASE_ADDR),
280 .length = MX21ADS_MMIO_SIZE,
281 .type = MT_DEVICE,
282 },
283};
284
285static void __init mx21ads_map_io(void)
286{
287 mx21_map_io();
288 iotable_init(mx21ads_io_desc, ARRAY_SIZE(mx21ads_io_desc));
289}
290
291static struct platform_device *platform_devices[] __initdata = {
292 &mx21ads_nor_mtd_device,
293};
294
295static void __init mx21ads_board_init(void)
296{
297 mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins),
298 "mx21ads");
299
300 mxc_register_device(&mxc_uart_device0, &uart_pdata);
301 mxc_register_device(&mxc_uart_device2, &uart_norts_pdata);
302 mxc_register_device(&mxc_uart_device3, &uart_pdata);
303 mxc_register_device(&mxc_fb_device, &mx21ads_fb_data);
304 mxc_register_device(&mxc_sdhc_device0, &mx21ads_sdhc_pdata);
305 mxc_register_device(&imx21_nand_device, &mx21ads_nand_board_info);
306
307 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
308}
309
310static void __init mx21ads_timer_init(void)
311{
312 mx21_clocks_init(32768, 26000000);
313}
314
315static struct sys_timer mx21ads_timer = {
316 .init = mx21ads_timer_init,
317};
318
319MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
320 /* maintainer: Freescale Semiconductor, Inc. */
321 .phys_io = MX21_AIPI_BASE_ADDR,
322 .io_pg_offst = ((MX21_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
323 .boot_params = MX21_PHYS_OFFSET + 0x100,
324 .map_io = mx21ads_map_io,
325 .init_irq = mx21_init_irq,
326 .init_machine = mx21ads_board_init,
327 .timer = &mx21ads_timer,
328MACHINE_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..a45df59ca72b
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -0,0 +1,100 @@
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 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * This machine is known as:
23 * - i.MX27 3-Stack Development System
24 * - i.MX27 Platform Development Kit (i.MX27 PDK)
25 */
26
27#include <linux/platform_device.h>
28#include <linux/gpio.h>
29#include <asm/mach-types.h>
30#include <asm/mach/arch.h>
31#include <asm/mach/time.h>
32#include <mach/hardware.h>
33#include <mach/common.h>
34#include <mach/imx-uart.h>
35#include <mach/iomux-mx27.h>
36
37#include "devices.h"
38
39static unsigned int mx27pdk_pins[] = {
40 /* UART1 */
41 PE12_PF_UART1_TXD,
42 PE13_PF_UART1_RXD,
43 PE14_PF_UART1_CTS,
44 PE15_PF_UART1_RTS,
45 /* FEC */
46 PD0_AIN_FEC_TXD0,
47 PD1_AIN_FEC_TXD1,
48 PD2_AIN_FEC_TXD2,
49 PD3_AIN_FEC_TXD3,
50 PD4_AOUT_FEC_RX_ER,
51 PD5_AOUT_FEC_RXD1,
52 PD6_AOUT_FEC_RXD2,
53 PD7_AOUT_FEC_RXD3,
54 PD8_AF_FEC_MDIO,
55 PD9_AIN_FEC_MDC,
56 PD10_AOUT_FEC_CRS,
57 PD11_AOUT_FEC_TX_CLK,
58 PD12_AOUT_FEC_RXD0,
59 PD13_AOUT_FEC_RX_DV,
60 PD14_AOUT_FEC_RX_CLK,
61 PD15_AOUT_FEC_COL,
62 PD16_AIN_FEC_TX_ER,
63 PF23_AIN_FEC_TX_EN,
64};
65
66static struct imxuart_platform_data uart_pdata = {
67 .flags = IMXUART_HAVE_RTSCTS,
68};
69
70static struct platform_device *platform_devices[] __initdata = {
71 &mxc_fec_device,
72};
73
74static void __init mx27pdk_init(void)
75{
76 mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
77 "mx27pdk");
78 mxc_register_device(&mxc_uart_device0, &uart_pdata);
79 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
80}
81
82static void __init mx27pdk_timer_init(void)
83{
84 mx27_clocks_init(26000000);
85}
86
87static struct sys_timer mx27pdk_timer = {
88 .init = mx27pdk_timer_init,
89};
90
91MACHINE_START(MX27_3DS, "Freescale MX27PDK")
92 /* maintainer: Freescale Semiconductor, Inc. */
93 .phys_io = MX27_AIPI_BASE_ADDR,
94 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
95 .boot_params = MX27_PHYS_OFFSET + 0x100,
96 .map_io = mx27_map_io,
97 .init_irq = mx27_init_irq,
98 .init_machine = mx27pdk_init,
99 .timer = &mx27pdk_timer,
100MACHINE_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..2183e3d4875a
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx27ads.c
@@ -0,0 +1,373 @@
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 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/platform_device.h>
22#include <linux/mtd/mtd.h>
23#include <linux/mtd/map.h>
24#include <linux/mtd/partitions.h>
25#include <linux/mtd/physmap.h>
26#include <linux/i2c.h>
27#include <linux/irq.h>
28#include <mach/common.h>
29#include <mach/hardware.h>
30#include <asm/mach-types.h>
31#include <asm/mach/arch.h>
32#include <asm/mach/time.h>
33#include <asm/mach/map.h>
34#include <mach/gpio.h>
35#include <mach/imx-uart.h>
36#include <mach/iomux-mx27.h>
37#include <mach/mxc_nand.h>
38#include <mach/i2c.h>
39#include <mach/imxfb.h>
40#include <mach/mmc.h>
41
42#include "devices.h"
43
44/*
45 * Base address of PBC controller, CS4
46 */
47#define PBC_BASE_ADDRESS 0xf4300000
48#define PBC_REG_ADDR(offset) (void __force __iomem *) \
49 (PBC_BASE_ADDRESS + (offset))
50
51/* When the PBC address connection is fixed in h/w, defined as 1 */
52#define PBC_ADDR_SH 0
53
54/* Offsets for the PBC Controller register */
55/*
56 * PBC Board version register offset
57 */
58#define PBC_VERSION_REG PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH)
59/*
60 * PBC Board control register 1 set address.
61 */
62#define PBC_BCTRL1_SET_REG PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH)
63/*
64 * PBC Board control register 1 clear address.
65 */
66#define PBC_BCTRL1_CLEAR_REG PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH)
67
68/* PBC Board Control Register 1 bit definitions */
69#define PBC_BCTRL1_LCDON 0x0800 /* Enable the LCD */
70
71/* to determine the correct external crystal reference */
72#define CKIH_27MHZ_BIT_SET (1 << 3)
73
74static unsigned int mx27ads_pins[] = {
75 /* UART0 */
76 PE12_PF_UART1_TXD,
77 PE13_PF_UART1_RXD,
78 PE14_PF_UART1_CTS,
79 PE15_PF_UART1_RTS,
80 /* UART1 */
81 PE3_PF_UART2_CTS,
82 PE4_PF_UART2_RTS,
83 PE6_PF_UART2_TXD,
84 PE7_PF_UART2_RXD,
85 /* UART2 */
86 PE8_PF_UART3_TXD,
87 PE9_PF_UART3_RXD,
88 PE10_PF_UART3_CTS,
89 PE11_PF_UART3_RTS,
90 /* UART3 */
91 PB26_AF_UART4_RTS,
92 PB28_AF_UART4_TXD,
93 PB29_AF_UART4_CTS,
94 PB31_AF_UART4_RXD,
95 /* UART4 */
96 PB18_AF_UART5_TXD,
97 PB19_AF_UART5_RXD,
98 PB20_AF_UART5_CTS,
99 PB21_AF_UART5_RTS,
100 /* UART5 */
101 PB10_AF_UART6_TXD,
102 PB12_AF_UART6_CTS,
103 PB11_AF_UART6_RXD,
104 PB13_AF_UART6_RTS,
105 /* FEC */
106 PD0_AIN_FEC_TXD0,
107 PD1_AIN_FEC_TXD1,
108 PD2_AIN_FEC_TXD2,
109 PD3_AIN_FEC_TXD3,
110 PD4_AOUT_FEC_RX_ER,
111 PD5_AOUT_FEC_RXD1,
112 PD6_AOUT_FEC_RXD2,
113 PD7_AOUT_FEC_RXD3,
114 PD8_AF_FEC_MDIO,
115 PD9_AIN_FEC_MDC,
116 PD10_AOUT_FEC_CRS,
117 PD11_AOUT_FEC_TX_CLK,
118 PD12_AOUT_FEC_RXD0,
119 PD13_AOUT_FEC_RX_DV,
120 PD14_AOUT_FEC_RX_CLK,
121 PD15_AOUT_FEC_COL,
122 PD16_AIN_FEC_TX_ER,
123 PF23_AIN_FEC_TX_EN,
124 /* I2C2 */
125 PC5_PF_I2C2_SDA,
126 PC6_PF_I2C2_SCL,
127 /* FB */
128 PA5_PF_LSCLK,
129 PA6_PF_LD0,
130 PA7_PF_LD1,
131 PA8_PF_LD2,
132 PA9_PF_LD3,
133 PA10_PF_LD4,
134 PA11_PF_LD5,
135 PA12_PF_LD6,
136 PA13_PF_LD7,
137 PA14_PF_LD8,
138 PA15_PF_LD9,
139 PA16_PF_LD10,
140 PA17_PF_LD11,
141 PA18_PF_LD12,
142 PA19_PF_LD13,
143 PA20_PF_LD14,
144 PA21_PF_LD15,
145 PA22_PF_LD16,
146 PA23_PF_LD17,
147 PA24_PF_REV,
148 PA25_PF_CLS,
149 PA26_PF_PS,
150 PA27_PF_SPL_SPR,
151 PA28_PF_HSYNC,
152 PA29_PF_VSYNC,
153 PA30_PF_CONTRAST,
154 PA31_PF_OE_ACD,
155 /* OWIRE */
156 PE16_AF_OWIRE,
157 /* SDHC1*/
158 PE18_PF_SD1_D0,
159 PE19_PF_SD1_D1,
160 PE20_PF_SD1_D2,
161 PE21_PF_SD1_D3,
162 PE22_PF_SD1_CMD,
163 PE23_PF_SD1_CLK,
164 /* SDHC2*/
165 PB4_PF_SD2_D0,
166 PB5_PF_SD2_D1,
167 PB6_PF_SD2_D2,
168 PB7_PF_SD2_D3,
169 PB8_PF_SD2_CMD,
170 PB9_PF_SD2_CLK,
171};
172
173static struct mxc_nand_platform_data mx27ads_nand_board_info = {
174 .width = 1,
175 .hw_ecc = 1,
176};
177
178/* ADS's NOR flash */
179static struct physmap_flash_data mx27ads_flash_data = {
180 .width = 2,
181};
182
183static struct resource mx27ads_flash_resource = {
184 .start = 0xc0000000,
185 .end = 0xc0000000 + 0x02000000 - 1,
186 .flags = IORESOURCE_MEM,
187
188};
189
190static struct platform_device mx27ads_nor_mtd_device = {
191 .name = "physmap-flash",
192 .id = 0,
193 .dev = {
194 .platform_data = &mx27ads_flash_data,
195 },
196 .num_resources = 1,
197 .resource = &mx27ads_flash_resource,
198};
199
200static struct imxi2c_platform_data mx27ads_i2c_data = {
201 .bitrate = 100000,
202};
203
204static struct i2c_board_info mx27ads_i2c_devices[] = {
205};
206
207void lcd_power(int on)
208{
209 if (on)
210 __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
211 else
212 __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
213}
214
215static struct imx_fb_videomode mx27ads_modes[] = {
216 {
217 .mode = {
218 .name = "Sharp-LQ035Q7",
219 .refresh = 60,
220 .xres = 240,
221 .yres = 320,
222 .pixclock = 188679, /* in ps (5.3MHz) */
223 .hsync_len = 1,
224 .left_margin = 9,
225 .right_margin = 16,
226 .vsync_len = 1,
227 .upper_margin = 7,
228 .lower_margin = 9,
229 },
230 .bpp = 16,
231 .pcr = 0xFB008BC0,
232 },
233};
234
235static struct imx_fb_platform_data mx27ads_fb_data = {
236 .mode = mx27ads_modes,
237 .num_modes = ARRAY_SIZE(mx27ads_modes),
238
239 /*
240 * - HSYNC active high
241 * - VSYNC active high
242 * - clk notenabled while idle
243 * - clock inverted
244 * - data not inverted
245 * - data enable low active
246 * - enable sharp mode
247 */
248 .pwmr = 0x00A903FF,
249 .lscr1 = 0x00120300,
250 .dmacr = 0x00020010,
251
252 .lcd_power = lcd_power,
253};
254
255static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
256 void *data)
257{
258 return request_irq(IRQ_GPIOE(21), detect_irq, IRQF_TRIGGER_RISING,
259 "sdhc1-card-detect", data);
260}
261
262static int mx27ads_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
263 void *data)
264{
265 return request_irq(IRQ_GPIOB(7), detect_irq, IRQF_TRIGGER_RISING,
266 "sdhc2-card-detect", data);
267}
268
269static void mx27ads_sdhc1_exit(struct device *dev, void *data)
270{
271 free_irq(IRQ_GPIOE(21), data);
272}
273
274static void mx27ads_sdhc2_exit(struct device *dev, void *data)
275{
276 free_irq(IRQ_GPIOB(7), data);
277}
278
279static struct imxmmc_platform_data sdhc1_pdata = {
280 .init = mx27ads_sdhc1_init,
281 .exit = mx27ads_sdhc1_exit,
282};
283
284static struct imxmmc_platform_data sdhc2_pdata = {
285 .init = mx27ads_sdhc2_init,
286 .exit = mx27ads_sdhc2_exit,
287};
288
289static struct platform_device *platform_devices[] __initdata = {
290 &mx27ads_nor_mtd_device,
291 &mxc_fec_device,
292 &mxc_w1_master_device,
293};
294
295static struct imxuart_platform_data uart_pdata[] = {
296 {
297 .flags = IMXUART_HAVE_RTSCTS,
298 }, {
299 .flags = IMXUART_HAVE_RTSCTS,
300 }, {
301 .flags = IMXUART_HAVE_RTSCTS,
302 }, {
303 .flags = IMXUART_HAVE_RTSCTS,
304 }, {
305 .flags = IMXUART_HAVE_RTSCTS,
306 }, {
307 .flags = IMXUART_HAVE_RTSCTS,
308 },
309};
310
311static void __init mx27ads_board_init(void)
312{
313 mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins),
314 "mx27ads");
315
316 mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
317 mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
318 mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
319 mxc_register_device(&mxc_uart_device3, &uart_pdata[3]);
320 mxc_register_device(&mxc_uart_device4, &uart_pdata[4]);
321 mxc_register_device(&mxc_uart_device5, &uart_pdata[5]);
322 mxc_register_device(&imx27_nand_device, &mx27ads_nand_board_info);
323
324 /* only the i2c master 1 is used on this CPU card */
325 i2c_register_board_info(1, mx27ads_i2c_devices,
326 ARRAY_SIZE(mx27ads_i2c_devices));
327 mxc_register_device(&mxc_i2c_device1, &mx27ads_i2c_data);
328 mxc_register_device(&mxc_fb_device, &mx27ads_fb_data);
329 mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
330 mxc_register_device(&mxc_sdhc_device1, &sdhc2_pdata);
331
332 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
333}
334
335static void __init mx27ads_timer_init(void)
336{
337 unsigned long fref = 26000000;
338
339 if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
340 fref = 27000000;
341
342 mx27_clocks_init(fref);
343}
344
345static struct sys_timer mx27ads_timer = {
346 .init = mx27ads_timer_init,
347};
348
349static struct map_desc mx27ads_io_desc[] __initdata = {
350 {
351 .virtual = PBC_BASE_ADDRESS,
352 .pfn = __phys_to_pfn(MX27_CS4_BASE_ADDR),
353 .length = SZ_1M,
354 .type = MT_DEVICE,
355 },
356};
357
358static void __init mx27ads_map_io(void)
359{
360 mx27_map_io();
361 iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
362}
363
364MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
365 /* maintainer: Freescale Semiconductor, Inc. */
366 .phys_io = MX27_AIPI_BASE_ADDR,
367 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
368 .boot_params = MX27_PHYS_OFFSET + 0x100,
369 .map_io = mx27ads_map_io,
370 .init_irq = mx27_init_irq,
371 .init_machine = mx27ads_board_init,
372 .timer = &mx27ads_timer,
373MACHINE_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..bc3855992677
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mxt_td60.c
@@ -0,0 +1,295 @@
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 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/platform_device.h>
22#include <linux/mtd/mtd.h>
23#include <linux/mtd/map.h>
24#include <linux/mtd/partitions.h>
25#include <linux/mtd/physmap.h>
26#include <linux/i2c.h>
27#include <linux/irq.h>
28#include <mach/common.h>
29#include <mach/hardware.h>
30#include <asm/mach-types.h>
31#include <asm/mach/arch.h>
32#include <asm/mach/time.h>
33#include <asm/mach/map.h>
34#include <linux/gpio.h>
35#include <mach/imx-uart.h>
36#include <mach/iomux-mx27.h>
37#include <mach/mxc_nand.h>
38#include <mach/i2c.h>
39#include <linux/i2c/pca953x.h>
40#include <mach/imxfb.h>
41#include <mach/mmc.h>
42
43#include "devices.h"
44
45static unsigned int mxt_td60_pins[] __initdata = {
46 /* UART0 */
47 PE12_PF_UART1_TXD,
48 PE13_PF_UART1_RXD,
49 PE14_PF_UART1_CTS,
50 PE15_PF_UART1_RTS,
51 /* UART1 */
52 PE3_PF_UART2_CTS,
53 PE4_PF_UART2_RTS,
54 PE6_PF_UART2_TXD,
55 PE7_PF_UART2_RXD,
56 /* UART2 */
57 PE8_PF_UART3_TXD,
58 PE9_PF_UART3_RXD,
59 PE10_PF_UART3_CTS,
60 PE11_PF_UART3_RTS,
61 /* FEC */
62 PD0_AIN_FEC_TXD0,
63 PD1_AIN_FEC_TXD1,
64 PD2_AIN_FEC_TXD2,
65 PD3_AIN_FEC_TXD3,
66 PD4_AOUT_FEC_RX_ER,
67 PD5_AOUT_FEC_RXD1,
68 PD6_AOUT_FEC_RXD2,
69 PD7_AOUT_FEC_RXD3,
70 PD8_AF_FEC_MDIO,
71 PD9_AIN_FEC_MDC,
72 PD10_AOUT_FEC_CRS,
73 PD11_AOUT_FEC_TX_CLK,
74 PD12_AOUT_FEC_RXD0,
75 PD13_AOUT_FEC_RX_DV,
76 PD14_AOUT_FEC_RX_CLK,
77 PD15_AOUT_FEC_COL,
78 PD16_AIN_FEC_TX_ER,
79 PF23_AIN_FEC_TX_EN,
80 /* I2C1 */
81 PD17_PF_I2C_DATA,
82 PD18_PF_I2C_CLK,
83 /* I2C2 */
84 PC5_PF_I2C2_SDA,
85 PC6_PF_I2C2_SCL,
86 /* FB */
87 PA5_PF_LSCLK,
88 PA6_PF_LD0,
89 PA7_PF_LD1,
90 PA8_PF_LD2,
91 PA9_PF_LD3,
92 PA10_PF_LD4,
93 PA11_PF_LD5,
94 PA12_PF_LD6,
95 PA13_PF_LD7,
96 PA14_PF_LD8,
97 PA15_PF_LD9,
98 PA16_PF_LD10,
99 PA17_PF_LD11,
100 PA18_PF_LD12,
101 PA19_PF_LD13,
102 PA20_PF_LD14,
103 PA21_PF_LD15,
104 PA22_PF_LD16,
105 PA23_PF_LD17,
106 PA25_PF_CLS,
107 PA27_PF_SPL_SPR,
108 PA28_PF_HSYNC,
109 PA29_PF_VSYNC,
110 PA30_PF_CONTRAST,
111 PA31_PF_OE_ACD,
112 /* OWIRE */
113 PE16_AF_OWIRE,
114 /* SDHC1*/
115 PE18_PF_SD1_D0,
116 PE19_PF_SD1_D1,
117 PE20_PF_SD1_D2,
118 PE21_PF_SD1_D3,
119 PE22_PF_SD1_CMD,
120 PE23_PF_SD1_CLK,
121 PF8_AF_ATA_IORDY,
122 /* SDHC2*/
123 PB4_PF_SD2_D0,
124 PB5_PF_SD2_D1,
125 PB6_PF_SD2_D2,
126 PB7_PF_SD2_D3,
127 PB8_PF_SD2_CMD,
128 PB9_PF_SD2_CLK,
129};
130
131static struct mxc_nand_platform_data mxt_td60_nand_board_info = {
132 .width = 1,
133 .hw_ecc = 1,
134};
135
136static struct imxi2c_platform_data mxt_td60_i2c_data = {
137 .bitrate = 100000,
138};
139
140/* PCA9557 */
141static int mxt_td60_pca9557_setup(struct i2c_client *client,
142 unsigned gpio_base, unsigned ngpio,
143 void *context)
144{
145 static int mxt_td60_gpio_value[] = {
146 -1, -1, -1, -1, -1, -1, -1, 1
147 };
148 int n;
149
150 for (n = 0; n < ARRAY_SIZE(mxt_td60_gpio_value); ++n) {
151 gpio_request(gpio_base + n, "MXT_TD60 GPIO Exp");
152 if (mxt_td60_gpio_value[n] < 0)
153 gpio_direction_input(gpio_base + n);
154 else
155 gpio_direction_output(gpio_base + n,
156 mxt_td60_gpio_value[n]);
157 gpio_export(gpio_base + n, 0);
158 }
159
160 return 0;
161}
162
163static struct pca953x_platform_data mxt_td60_pca9557_pdata = {
164 .gpio_base = 240, /* place PCA9557 after all MX27 gpio pins */
165 .invert = 0, /* Do not invert */
166 .setup = mxt_td60_pca9557_setup,
167};
168
169static struct i2c_board_info mxt_td60_i2c_devices[] = {
170 {
171 I2C_BOARD_INFO("pca9557", 0x18),
172 .platform_data = &mxt_td60_pca9557_pdata,
173 },
174};
175
176static struct imxi2c_platform_data mxt_td60_i2c2_data = {
177 .bitrate = 100000,
178};
179
180static struct i2c_board_info mxt_td60_i2c2_devices[] = {
181};
182
183static struct imx_fb_videomode mxt_td60_modes[] = {
184 {
185 .mode = {
186 .name = "Chimei LW700AT9003",
187 .refresh = 60,
188 .xres = 800,
189 .yres = 480,
190 .pixclock = 30303,
191 .hsync_len = 64,
192 .left_margin = 0x67,
193 .right_margin = 0x68,
194 .vsync_len = 16,
195 .upper_margin = 0x0f,
196 .lower_margin = 0x0f,
197 },
198 .bpp = 16,
199 .pcr = 0xFA208B83,
200 },
201};
202
203static struct imx_fb_platform_data mxt_td60_fb_data = {
204 .mode = mxt_td60_modes,
205 .num_modes = ARRAY_SIZE(mxt_td60_modes),
206
207 /*
208 * - HSYNC active high
209 * - VSYNC active high
210 * - clk notenabled while idle
211 * - clock inverted
212 * - data not inverted
213 * - data enable low active
214 * - enable sharp mode
215 */
216 .pwmr = 0x00A903FF,
217 .lscr1 = 0x00120300,
218 .dmacr = 0x00020010,
219};
220
221static int mxt_td60_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
222 void *data)
223{
224 return request_irq(IRQ_GPIOF(8), detect_irq, IRQF_TRIGGER_FALLING,
225 "sdhc1-card-detect", data);
226}
227
228static void mxt_td60_sdhc1_exit(struct device *dev, void *data)
229{
230 free_irq(IRQ_GPIOF(8), data);
231}
232
233static struct imxmmc_platform_data sdhc1_pdata = {
234 .init = mxt_td60_sdhc1_init,
235 .exit = mxt_td60_sdhc1_exit,
236};
237
238static struct platform_device *platform_devices[] __initdata = {
239 &mxc_fec_device,
240};
241
242static struct imxuart_platform_data uart_pdata[] = {
243 {
244 .flags = IMXUART_HAVE_RTSCTS,
245 }, {
246 .flags = IMXUART_HAVE_RTSCTS,
247 }, {
248 .flags = IMXUART_HAVE_RTSCTS,
249 },
250};
251
252static void __init mxt_td60_board_init(void)
253{
254 mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins),
255 "MXT_TD60");
256
257 mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
258 mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
259 mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
260 mxc_register_device(&imx27_nand_device, &mxt_td60_nand_board_info);
261
262 i2c_register_board_info(0, mxt_td60_i2c_devices,
263 ARRAY_SIZE(mxt_td60_i2c_devices));
264
265 i2c_register_board_info(1, mxt_td60_i2c2_devices,
266 ARRAY_SIZE(mxt_td60_i2c2_devices));
267
268 mxc_register_device(&mxc_i2c_device0, &mxt_td60_i2c_data);
269 mxc_register_device(&mxc_i2c_device1, &mxt_td60_i2c2_data);
270 mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data);
271 mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
272
273 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
274}
275
276static void __init mxt_td60_timer_init(void)
277{
278 mx27_clocks_init(26000000);
279}
280
281static struct sys_timer mxt_td60_timer = {
282 .init = mxt_td60_timer_init,
283};
284
285MACHINE_START(MXT_TD60, "Maxtrack i-MXT TD60")
286 /* maintainer: Maxtrack Industrial */
287 .phys_io = MX27_AIPI_BASE_ADDR,
288 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
289 .boot_params = MX27_PHYS_OFFSET + 0x100,
290 .map_io = mx27_map_io,
291 .init_irq = mx27_init_irq,
292 .init_machine = mxt_td60_board_init,
293 .timer = &mxt_td60_timer,
294MACHINE_END
295
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
new file mode 100644
index 000000000000..a87422ed4ff5
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -0,0 +1,396 @@
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 <mach/i2c.h>
40#include <asm/mach/time.h>
41#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
42#include <mach/spi.h>
43#endif
44#include <mach/imx-uart.h>
45#include <mach/audmux.h>
46#include <mach/ssi.h>
47#include <mach/mxc_nand.h>
48#include <mach/irqs.h>
49#include <mach/mmc.h>
50#include <mach/mxc_ehci.h>
51#include <mach/ulpi.h>
52
53#include "devices.h"
54
55#define OTG_PHY_CS_GPIO (GPIO_PORTB + 23)
56#define USBH2_PHY_CS_GPIO (GPIO_PORTB + 24)
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 /* FEC */
72 PD0_AIN_FEC_TXD0,
73 PD1_AIN_FEC_TXD1,
74 PD2_AIN_FEC_TXD2,
75 PD3_AIN_FEC_TXD3,
76 PD4_AOUT_FEC_RX_ER,
77 PD5_AOUT_FEC_RXD1,
78 PD6_AOUT_FEC_RXD2,
79 PD7_AOUT_FEC_RXD3,
80 PD8_AF_FEC_MDIO,
81 PD9_AIN_FEC_MDC,
82 PD10_AOUT_FEC_CRS,
83 PD11_AOUT_FEC_TX_CLK,
84 PD12_AOUT_FEC_RXD0,
85 PD13_AOUT_FEC_RX_DV,
86 PD14_AOUT_FEC_RX_CLK,
87 PD15_AOUT_FEC_COL,
88 PD16_AIN_FEC_TX_ER,
89 PF23_AIN_FEC_TX_EN,
90 /* SSI1 */
91 PC20_PF_SSI1_FS,
92 PC21_PF_SSI1_RXD,
93 PC22_PF_SSI1_TXD,
94 PC23_PF_SSI1_CLK,
95 /* onboard I2C */
96 PC5_PF_I2C2_SDA,
97 PC6_PF_I2C2_SCL,
98 /* external I2C */
99 PD17_PF_I2C_DATA,
100 PD18_PF_I2C_CLK,
101 /* SPI1 */
102 PD25_PF_CSPI1_RDY,
103 PD29_PF_CSPI1_SCLK,
104 PD30_PF_CSPI1_MISO,
105 PD31_PF_CSPI1_MOSI,
106 /* OTG */
107 OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
108 PC7_PF_USBOTG_DATA5,
109 PC8_PF_USBOTG_DATA6,
110 PC9_PF_USBOTG_DATA0,
111 PC10_PF_USBOTG_DATA2,
112 PC11_PF_USBOTG_DATA1,
113 PC12_PF_USBOTG_DATA4,
114 PC13_PF_USBOTG_DATA3,
115 PE0_PF_USBOTG_NXT,
116 PE1_PF_USBOTG_STP,
117 PE2_PF_USBOTG_DIR,
118 PE24_PF_USBOTG_CLK,
119 PE25_PF_USBOTG_DATA7,
120 /* USBH2 */
121 USBH2_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
122 PA0_PF_USBH2_CLK,
123 PA1_PF_USBH2_DIR,
124 PA2_PF_USBH2_DATA7,
125 PA3_PF_USBH2_NXT,
126 PA4_PF_USBH2_STP,
127 PD19_AF_USBH2_DATA4,
128 PD20_AF_USBH2_DATA3,
129 PD21_AF_USBH2_DATA6,
130 PD22_AF_USBH2_DATA0,
131 PD23_AF_USBH2_DATA2,
132 PD24_AF_USBH2_DATA1,
133 PD26_AF_USBH2_DATA5,
134};
135
136static struct imxuart_platform_data uart_pdata = {
137 .flags = IMXUART_HAVE_RTSCTS,
138};
139
140static struct mxc_nand_platform_data pca100_nand_board_info = {
141 .width = 1,
142 .hw_ecc = 1,
143};
144
145static struct platform_device *platform_devices[] __initdata = {
146 &mxc_w1_master_device,
147 &mxc_fec_device,
148 &mxc_wdt,
149};
150
151static struct imxi2c_platform_data pca100_i2c_1_data = {
152 .bitrate = 100000,
153};
154
155static struct at24_platform_data board_eeprom = {
156 .byte_len = 4096,
157 .page_size = 32,
158 .flags = AT24_FLAG_ADDR16,
159};
160
161static struct i2c_board_info pca100_i2c_devices[] = {
162 {
163 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
164 .platform_data = &board_eeprom,
165 }, {
166 I2C_BOARD_INFO("rtc-pcf8563", 0x51),
167 .type = "pcf8563"
168 }, {
169 I2C_BOARD_INFO("lm75", 0x4a),
170 .type = "lm75"
171 }
172};
173
174#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
175static struct spi_eeprom at25320 = {
176 .name = "at25320an",
177 .byte_len = 4096,
178 .page_size = 32,
179 .flags = EE_ADDR2,
180};
181
182static struct spi_board_info pca100_spi_board_info[] __initdata = {
183 {
184 .modalias = "at25",
185 .max_speed_hz = 30000,
186 .bus_num = 0,
187 .chip_select = 1,
188 .platform_data = &at25320,
189 },
190};
191
192static int pca100_spi_cs[] = {GPIO_PORTD + 28, GPIO_PORTD + 27};
193
194static struct spi_imx_master pca100_spi_0_data = {
195 .chipselect = pca100_spi_cs,
196 .num_chipselect = ARRAY_SIZE(pca100_spi_cs),
197};
198#endif
199
200static void pca100_ac97_warm_reset(struct snd_ac97 *ac97)
201{
202 mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT);
203 gpio_set_value(GPIO_PORTC + 20, 1);
204 udelay(2);
205 gpio_set_value(GPIO_PORTC + 20, 0);
206 mxc_gpio_mode(PC20_PF_SSI1_FS);
207 msleep(2);
208}
209
210static void pca100_ac97_cold_reset(struct snd_ac97 *ac97)
211{
212 mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT); /* FS */
213 gpio_set_value(GPIO_PORTC + 20, 0);
214 mxc_gpio_mode(GPIO_PORTC | 22 | GPIO_GPIO | GPIO_OUT); /* TX */
215 gpio_set_value(GPIO_PORTC + 22, 0);
216 mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_OUT); /* reset */
217 gpio_set_value(GPIO_PORTC + 28, 0);
218 udelay(10);
219 gpio_set_value(GPIO_PORTC + 28, 1);
220 mxc_gpio_mode(PC20_PF_SSI1_FS);
221 mxc_gpio_mode(PC22_PF_SSI1_TXD);
222 msleep(2);
223}
224
225static struct imx_ssi_platform_data pca100_ssi_pdata = {
226 .ac97_reset = pca100_ac97_cold_reset,
227 .ac97_warm_reset = pca100_ac97_warm_reset,
228 .flags = IMX_SSI_USE_AC97,
229};
230
231static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
232 void *data)
233{
234 int ret;
235
236 ret = request_irq(IRQ_GPIOC(29), detect_irq,
237 IRQF_DISABLED | IRQF_TRIGGER_FALLING,
238 "imx-mmc-detect", data);
239 if (ret)
240 printk(KERN_ERR
241 "pca100: Failed to reuest irq for sd/mmc detection\n");
242
243 return ret;
244}
245
246static void pca100_sdhc2_exit(struct device *dev, void *data)
247{
248 free_irq(IRQ_GPIOC(29), data);
249}
250
251static struct imxmmc_platform_data sdhc_pdata = {
252 .init = pca100_sdhc2_init,
253 .exit = pca100_sdhc2_exit,
254};
255
256static int otg_phy_init(struct platform_device *pdev)
257{
258 gpio_set_value(OTG_PHY_CS_GPIO, 0);
259 return 0;
260}
261
262static struct mxc_usbh_platform_data otg_pdata = {
263 .init = otg_phy_init,
264 .portsc = MXC_EHCI_MODE_ULPI,
265 .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
266};
267
268static int usbh2_phy_init(struct platform_device *pdev)
269{
270 gpio_set_value(USBH2_PHY_CS_GPIO, 0);
271 return 0;
272}
273
274static struct mxc_usbh_platform_data usbh2_pdata = {
275 .init = usbh2_phy_init,
276 .portsc = MXC_EHCI_MODE_ULPI,
277 .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
278};
279
280static struct fsl_usb2_platform_data otg_device_pdata = {
281 .operating_mode = FSL_USB2_DR_DEVICE,
282 .phy_mode = FSL_USB2_PHY_ULPI,
283};
284
285static int otg_mode_host;
286
287static int __init pca100_otg_mode(char *options)
288{
289 if (!strcmp(options, "host"))
290 otg_mode_host = 1;
291 else if (!strcmp(options, "device"))
292 otg_mode_host = 0;
293 else
294 pr_info("otg_mode neither \"host\" nor \"device\". "
295 "Defaulting to device\n");
296 return 0;
297}
298__setup("otg_mode=", pca100_otg_mode);
299
300static void __init pca100_init(void)
301{
302 int ret;
303
304 /* SSI unit */
305 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
306 MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
307 MXC_AUDMUX_V1_PCR_TFCSEL(3) |
308 MXC_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
309 MXC_AUDMUX_V1_PCR_RXDSEL(3));
310 mxc_audmux_v1_configure_port(3,
311 MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
312 MXC_AUDMUX_V1_PCR_TFCSEL(0) |
313 MXC_AUDMUX_V1_PCR_TFSDIR |
314 MXC_AUDMUX_V1_PCR_RXDSEL(0));
315
316 ret = mxc_gpio_setup_multiple_pins(pca100_pins,
317 ARRAY_SIZE(pca100_pins), "PCA100");
318 if (ret)
319 printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret);
320
321 mxc_register_device(&imx_ssi_device0, &pca100_ssi_pdata);
322
323 mxc_register_device(&mxc_uart_device0, &uart_pdata);
324
325 mxc_gpio_mode(GPIO_PORTC | 29 | GPIO_GPIO | GPIO_IN);
326 mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
327
328 mxc_register_device(&imx27_nand_device, &pca100_nand_board_info);
329
330 /* only the i2c master 1 is used on this CPU card */
331 i2c_register_board_info(1, pca100_i2c_devices,
332 ARRAY_SIZE(pca100_i2c_devices));
333
334 mxc_register_device(&mxc_i2c_device1, &pca100_i2c_1_data);
335
336 mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
337 mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_OUT);
338
339 /* GPIO0_IRQ */
340 mxc_gpio_mode(GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN);
341 /* GPIO1_IRQ */
342 mxc_gpio_mode(GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN);
343 /* GPIO2_IRQ */
344 mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN);
345
346#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
347 spi_register_board_info(pca100_spi_board_info,
348 ARRAY_SIZE(pca100_spi_board_info));
349 mxc_register_device(&mxc_spi_device0, &pca100_spi_0_data);
350#endif
351
352 gpio_request(OTG_PHY_CS_GPIO, "usb-otg-cs");
353 gpio_direction_output(OTG_PHY_CS_GPIO, 1);
354 gpio_request(USBH2_PHY_CS_GPIO, "usb-host2-cs");
355 gpio_direction_output(USBH2_PHY_CS_GPIO, 1);
356
357#if defined(CONFIG_USB_ULPI)
358 if (otg_mode_host) {
359 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
360 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
361
362 mxc_register_device(&mxc_otg_host, &otg_pdata);
363 }
364
365 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
366 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
367
368 mxc_register_device(&mxc_usbh2, &usbh2_pdata);
369#endif
370 if (!otg_mode_host) {
371 gpio_set_value(OTG_PHY_CS_GPIO, 0);
372 mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
373 }
374
375 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
376}
377
378static void __init pca100_timer_init(void)
379{
380 mx27_clocks_init(26000000);
381}
382
383static struct sys_timer pca100_timer = {
384 .init = pca100_timer_init,
385};
386
387MACHINE_START(PCA100, "phyCARD-i.MX27")
388 .phys_io = MX27_AIPI_BASE_ADDR,
389 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
390 .boot_params = MX27_PHYS_OFFSET + 0x100,
391 .map_io = mx27_map_io,
392 .init_irq = mx27_init_irq,
393 .init_machine = pca100_init,
394 .timer = &pca100_timer,
395MACHINE_END
396
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c
new file mode 100644
index 000000000000..36c89431679a
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pcm038.c
@@ -0,0 +1,359 @@
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/i2c.h>
39#include <mach/iomux-mx27.h>
40#include <mach/imx-uart.h>
41#include <mach/mxc_nand.h>
42#include <mach/spi.h>
43#include <mach/mxc_ehci.h>
44#include <mach/ulpi.h>
45
46#include "devices.h"
47
48static int pcm038_pins[] = {
49 /* UART1 */
50 PE12_PF_UART1_TXD,
51 PE13_PF_UART1_RXD,
52 PE14_PF_UART1_CTS,
53 PE15_PF_UART1_RTS,
54 /* UART2 */
55 PE3_PF_UART2_CTS,
56 PE4_PF_UART2_RTS,
57 PE6_PF_UART2_TXD,
58 PE7_PF_UART2_RXD,
59 /* UART3 */
60 PE8_PF_UART3_TXD,
61 PE9_PF_UART3_RXD,
62 PE10_PF_UART3_CTS,
63 PE11_PF_UART3_RTS,
64 /* FEC */
65 PD0_AIN_FEC_TXD0,
66 PD1_AIN_FEC_TXD1,
67 PD2_AIN_FEC_TXD2,
68 PD3_AIN_FEC_TXD3,
69 PD4_AOUT_FEC_RX_ER,
70 PD5_AOUT_FEC_RXD1,
71 PD6_AOUT_FEC_RXD2,
72 PD7_AOUT_FEC_RXD3,
73 PD8_AF_FEC_MDIO,
74 PD9_AIN_FEC_MDC,
75 PD10_AOUT_FEC_CRS,
76 PD11_AOUT_FEC_TX_CLK,
77 PD12_AOUT_FEC_RXD0,
78 PD13_AOUT_FEC_RX_DV,
79 PD14_AOUT_FEC_RX_CLK,
80 PD15_AOUT_FEC_COL,
81 PD16_AIN_FEC_TX_ER,
82 PF23_AIN_FEC_TX_EN,
83 /* I2C2 */
84 PC5_PF_I2C2_SDA,
85 PC6_PF_I2C2_SCL,
86 /* SPI1 */
87 PD25_PF_CSPI1_RDY,
88 PD29_PF_CSPI1_SCLK,
89 PD30_PF_CSPI1_MISO,
90 PD31_PF_CSPI1_MOSI,
91 /* SSI1 */
92 PC20_PF_SSI1_FS,
93 PC21_PF_SSI1_RXD,
94 PC22_PF_SSI1_TXD,
95 PC23_PF_SSI1_CLK,
96 /* SSI4 */
97 PC16_PF_SSI4_FS,
98 PC17_PF_SSI4_RXD,
99 PC18_PF_SSI4_TXD,
100 PC19_PF_SSI4_CLK,
101 /* USB host */
102 PA0_PF_USBH2_CLK,
103 PA1_PF_USBH2_DIR,
104 PA2_PF_USBH2_DATA7,
105 PA3_PF_USBH2_NXT,
106 PA4_PF_USBH2_STP,
107 PD19_AF_USBH2_DATA4,
108 PD20_AF_USBH2_DATA3,
109 PD21_AF_USBH2_DATA6,
110 PD22_AF_USBH2_DATA0,
111 PD23_AF_USBH2_DATA2,
112 PD24_AF_USBH2_DATA1,
113 PD26_AF_USBH2_DATA5,
114};
115
116/*
117 * Phytec's PCM038 comes with 2MiB battery buffered SRAM,
118 * 16 bit width
119 */
120
121static struct platdata_mtd_ram pcm038_sram_data = {
122 .bankwidth = 2,
123};
124
125static struct resource pcm038_sram_resource = {
126 .start = MX27_CS1_BASE_ADDR,
127 .end = MX27_CS1_BASE_ADDR + 512 * 1024 - 1,
128 .flags = IORESOURCE_MEM,
129};
130
131static struct platform_device pcm038_sram_mtd_device = {
132 .name = "mtd-ram",
133 .id = 0,
134 .dev = {
135 .platform_data = &pcm038_sram_data,
136 },
137 .num_resources = 1,
138 .resource = &pcm038_sram_resource,
139};
140
141/*
142 * Phytec's phyCORE-i.MX27 comes with 32MiB flash,
143 * 16 bit width
144 */
145static struct physmap_flash_data pcm038_flash_data = {
146 .width = 2,
147};
148
149static struct resource pcm038_flash_resource = {
150 .start = 0xc0000000,
151 .end = 0xc1ffffff,
152 .flags = IORESOURCE_MEM,
153};
154
155static struct platform_device pcm038_nor_mtd_device = {
156 .name = "physmap-flash",
157 .id = 0,
158 .dev = {
159 .platform_data = &pcm038_flash_data,
160 },
161 .num_resources = 1,
162 .resource = &pcm038_flash_resource,
163};
164
165static struct imxuart_platform_data uart_pdata[] = {
166 {
167 .flags = IMXUART_HAVE_RTSCTS,
168 }, {
169 .flags = IMXUART_HAVE_RTSCTS,
170 }, {
171 .flags = IMXUART_HAVE_RTSCTS,
172 },
173};
174
175static struct mxc_nand_platform_data pcm038_nand_board_info = {
176 .width = 1,
177 .hw_ecc = 1,
178};
179
180static struct platform_device *platform_devices[] __initdata = {
181 &pcm038_nor_mtd_device,
182 &mxc_w1_master_device,
183 &mxc_fec_device,
184 &pcm038_sram_mtd_device,
185 &mxc_wdt,
186};
187
188/* On pcm038 there's a sram attached to CS1, we enable the chipselect here and
189 * setup other stuffs to access the sram. */
190static void __init pcm038_init_sram(void)
191{
192 mx27_setup_weimcs(1, 0x0000d843, 0x22252521, 0x22220a00);
193}
194
195static struct imxi2c_platform_data pcm038_i2c_1_data = {
196 .bitrate = 100000,
197};
198
199static struct at24_platform_data board_eeprom = {
200 .byte_len = 4096,
201 .page_size = 32,
202 .flags = AT24_FLAG_ADDR16,
203};
204
205static struct i2c_board_info pcm038_i2c_devices[] = {
206 {
207 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
208 .platform_data = &board_eeprom,
209 }, {
210 I2C_BOARD_INFO("pcf8563", 0x51),
211 }, {
212 I2C_BOARD_INFO("lm75", 0x4a),
213 }
214};
215
216static int pcm038_spi_cs[] = {GPIO_PORTD + 28};
217
218static struct spi_imx_master pcm038_spi_0_data = {
219 .chipselect = pcm038_spi_cs,
220 .num_chipselect = ARRAY_SIZE(pcm038_spi_cs),
221};
222
223static struct regulator_consumer_supply sdhc1_consumers[] = {
224 {
225 .dev = &mxc_sdhc_device1.dev,
226 .supply = "sdhc_vcc",
227 },
228};
229
230static struct regulator_init_data sdhc1_data = {
231 .constraints = {
232 .min_uV = 3000000,
233 .max_uV = 3400000,
234 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
235 REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
236 .valid_modes_mask = REGULATOR_MODE_NORMAL |
237 REGULATOR_MODE_FAST,
238 .always_on = 0,
239 .boot_on = 0,
240 },
241 .num_consumer_supplies = ARRAY_SIZE(sdhc1_consumers),
242 .consumer_supplies = sdhc1_consumers,
243};
244
245static struct regulator_consumer_supply cam_consumers[] = {
246 {
247 .dev = NULL,
248 .supply = "imx_cam_vcc",
249 },
250};
251
252static struct regulator_init_data cam_data = {
253 .constraints = {
254 .min_uV = 3000000,
255 .max_uV = 3400000,
256 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
257 REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
258 .valid_modes_mask = REGULATOR_MODE_NORMAL |
259 REGULATOR_MODE_FAST,
260 .always_on = 0,
261 .boot_on = 0,
262 },
263 .num_consumer_supplies = ARRAY_SIZE(cam_consumers),
264 .consumer_supplies = cam_consumers,
265};
266
267struct mc13783_regulator_init_data pcm038_regulators[] = {
268 {
269 .id = MC13783_REGU_VCAM,
270 .init_data = &cam_data,
271 }, {
272 .id = MC13783_REGU_VMMC1,
273 .init_data = &sdhc1_data,
274 },
275};
276
277static struct mc13783_platform_data pcm038_pmic = {
278 .regulators = pcm038_regulators,
279 .num_regulators = ARRAY_SIZE(pcm038_regulators),
280 .flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
281 MC13783_USE_TOUCHSCREEN,
282};
283
284static struct spi_board_info pcm038_spi_board_info[] __initdata = {
285 {
286 .modalias = "mc13783",
287 .irq = IRQ_GPIOB(23),
288 .max_speed_hz = 300000,
289 .bus_num = 0,
290 .chip_select = 0,
291 .platform_data = &pcm038_pmic,
292 .mode = SPI_CS_HIGH,
293 }
294};
295
296static struct mxc_usbh_platform_data usbh2_pdata = {
297 .portsc = MXC_EHCI_MODE_ULPI,
298 .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
299};
300
301static void __init pcm038_init(void)
302{
303 mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
304 "PCM038");
305
306 pcm038_init_sram();
307
308 mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
309 mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
310 mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
311
312 mxc_gpio_mode(PE16_AF_OWIRE);
313 mxc_register_device(&imx27_nand_device, &pcm038_nand_board_info);
314
315 /* only the i2c master 1 is used on this CPU card */
316 i2c_register_board_info(1, pcm038_i2c_devices,
317 ARRAY_SIZE(pcm038_i2c_devices));
318
319 mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data);
320
321 /* PE18 for user-LED D40 */
322 mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
323
324 mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
325
326 /* MC13783 IRQ */
327 mxc_gpio_mode(GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN);
328
329 mxc_register_device(&mxc_spi_device0, &pcm038_spi_0_data);
330 spi_register_board_info(pcm038_spi_board_info,
331 ARRAY_SIZE(pcm038_spi_board_info));
332
333 mxc_register_device(&mxc_usbh2, &usbh2_pdata);
334
335 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
336
337#ifdef CONFIG_MACH_PCM970_BASEBOARD
338 pcm970_baseboard_init();
339#endif
340}
341
342static void __init pcm038_timer_init(void)
343{
344 mx27_clocks_init(26000000);
345}
346
347static struct sys_timer pcm038_timer = {
348 .init = pcm038_timer_init,
349};
350
351MACHINE_START(PCM038, "phyCORE-i.MX27")
352 .phys_io = MX27_AIPI_BASE_ADDR,
353 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
354 .boot_params = MX27_PHYS_OFFSET + 0x100,
355 .map_io = mx27_map_io,
356 .init_irq = mx27_init_irq,
357 .init_machine = pcm038_init,
358 .timer = &pcm038_timer,
359MACHINE_END
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
new file mode 100644
index 000000000000..115c21289125
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -0,0 +1,83 @@
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
80void __init mx21_init_irq(void)
81{
82 mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
83}
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
new file mode 100644
index 000000000000..89b41749e166
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -0,0 +1,83 @@
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
80void __init mx27_init_irq(void)
81{
82 mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
83}
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/serial.c b/arch/arm/mach-imx/serial.c
new file mode 100644
index 000000000000..1c0c835b2252
--- /dev/null
+++ b/arch/arm/mach-imx/serial.c
@@ -0,0 +1,141 @@
1/*
2 * Copyright 2006-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#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/serial.h>
23#include <mach/hardware.h>
24#include <mach/imx-uart.h>
25#include "devices.h"
26
27static struct resource uart0[] = {
28 {
29 .start = MX2x_UART1_BASE_ADDR,
30 .end = MX2x_UART1_BASE_ADDR + 0x0B5,
31 .flags = IORESOURCE_MEM,
32 }, {
33 .start = MX2x_INT_UART1,
34 .end = MX2x_INT_UART1,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device mxc_uart_device0 = {
40 .name = "imx-uart",
41 .id = 0,
42 .resource = uart0,
43 .num_resources = ARRAY_SIZE(uart0),
44};
45
46static struct resource uart1[] = {
47 {
48 .start = MX2x_UART2_BASE_ADDR,
49 .end = MX2x_UART2_BASE_ADDR + 0x0B5,
50 .flags = IORESOURCE_MEM,
51 }, {
52 .start = MX2x_INT_UART2,
53 .end = MX2x_INT_UART2,
54 .flags = IORESOURCE_IRQ,
55 },
56};
57
58struct platform_device mxc_uart_device1 = {
59 .name = "imx-uart",
60 .id = 1,
61 .resource = uart1,
62 .num_resources = ARRAY_SIZE(uart1),
63};
64
65static struct resource uart2[] = {
66 {
67 .start = MX2x_UART3_BASE_ADDR,
68 .end = MX2x_UART3_BASE_ADDR + 0x0B5,
69 .flags = IORESOURCE_MEM,
70 }, {
71 .start = MX2x_INT_UART3,
72 .end = MX2x_INT_UART3,
73 .flags = IORESOURCE_IRQ,
74 },
75};
76
77struct platform_device mxc_uart_device2 = {
78 .name = "imx-uart",
79 .id = 2,
80 .resource = uart2,
81 .num_resources = ARRAY_SIZE(uart2),
82};
83
84static struct resource uart3[] = {
85 {
86 .start = MX2x_UART4_BASE_ADDR,
87 .end = MX2x_UART4_BASE_ADDR + 0x0B5,
88 .flags = IORESOURCE_MEM,
89 }, {
90 .start = MX2x_INT_UART4,
91 .end = MX2x_INT_UART4,
92 .flags = IORESOURCE_IRQ,
93 },
94};
95
96struct platform_device mxc_uart_device3 = {
97 .name = "imx-uart",
98 .id = 3,
99 .resource = uart3,
100 .num_resources = ARRAY_SIZE(uart3),
101};
102
103#ifdef CONFIG_MACH_MX27
104static struct resource uart4[] = {
105 {
106 .start = MX27_UART5_BASE_ADDR,
107 .end = MX27_UART5_BASE_ADDR + 0x0B5,
108 .flags = IORESOURCE_MEM,
109 }, {
110 .start = MX27_INT_UART5,
111 .end = MX27_INT_UART5,
112 .flags = IORESOURCE_IRQ,
113 },
114};
115
116struct platform_device mxc_uart_device4 = {
117 .name = "imx-uart",
118 .id = 4,
119 .resource = uart4,
120 .num_resources = ARRAY_SIZE(uart4),
121};
122
123static struct resource uart5[] = {
124 {
125 .start = MX27_UART6_BASE_ADDR,
126 .end = MX27_UART6_BASE_ADDR + 0x0B5,
127 .flags = IORESOURCE_MEM,
128 }, {
129 .start = MX27_INT_UART6,
130 .end = MX27_INT_UART6,
131 .flags = IORESOURCE_IRQ,
132 },
133};
134
135struct platform_device mxc_uart_device5 = {
136 .name = "imx-uart",
137 .id = 5,
138 .resource = uart5,
139 .num_resources = ARRAY_SIZE(uart5),
140};
141#endif