aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa
diff options
context:
space:
mode:
authoreric miao <eric.y.miao@gmail.com>2007-09-11 22:13:17 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-10-15 13:53:43 -0400
commit2c8086a5d073e8e72122a5b84febde236a39845b (patch)
treeb926ccc2231d7e287400d4fbf24f509c9a8225ae /arch/arm/mach-pxa
parent073ac8fd4a3e9a9265e8a59e0a79bc4b0b3822c3 (diff)
[ARM] pxa: PXA3xx base support
Signed-off-by: eric miao <eric.y.miao@gmail.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r--arch/arm/mach-pxa/Kconfig29
-rw-r--r--arch/arm/mach-pxa/Makefile9
-rw-r--r--arch/arm/mach-pxa/generic.c8
-rw-r--r--arch/arm/mach-pxa/generic.h8
-rw-r--r--arch/arm/mach-pxa/irq.c2
-rw-r--r--arch/arm/mach-pxa/mfp.c235
-rw-r--r--arch/arm/mach-pxa/pxa300.c93
-rw-r--r--arch/arm/mach-pxa/pxa320.c88
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c216
-rw-r--r--arch/arm/mach-pxa/zylonite.c184
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa300.c188
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa320.c173
12 files changed, 1229 insertions, 4 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 5ebec6d88b51..e895188cadcd 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -1,6 +1,24 @@
1if ARCH_PXA 1if ARCH_PXA
2 2
3menu "Intel PXA2xx Implementations" 3menu "Intel PXA2xx/PXA3xx Implementations"
4
5if PXA3xx
6
7menu "Supported PXA3xx Processor Variants"
8
9config CPU_PXA300
10 bool "PXA300 (codename Monahans-L)"
11
12config CPU_PXA310
13 bool "PXA310 (codename Monahans-LV)"
14 select CPU_PXA300
15
16config CPU_PXA320
17 bool "PXA320 (codename Monahans-P)"
18
19endmenu
20
21endif
4 22
5choice 23choice
6 prompt "Select target board" 24 prompt "Select target board"
@@ -41,6 +59,10 @@ config MACH_EM_X270
41 bool "CompuLab EM-x270 platform" 59 bool "CompuLab EM-x270 platform"
42 select PXA27x 60 select PXA27x
43 61
62config MACH_ZYLONITE
63 bool "PXA3xx Development Platform"
64 select PXA3xx
65
44endchoice 66endchoice
45 67
46if PXA_SHARPSL 68if PXA_SHARPSL
@@ -130,6 +152,11 @@ config PXA27x
130 help 152 help
131 Select code specific to PXA27x variants 153 Select code specific to PXA27x variants
132 154
155config PXA3xx
156 bool
157 help
158 Select code specific to PXA3xx variants
159
133config PXA_SHARP_C7xx 160config PXA_SHARP_C7xx
134 bool 161 bool
135 select PXA_SSP 162 select PXA_SSP
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 8970928fbcaa..bfdd0c5fcd7a 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -6,6 +6,9 @@
6obj-y += clock.o generic.o irq.o dma.o time.o 6obj-y += clock.o generic.o irq.o dma.o time.o
7obj-$(CONFIG_PXA25x) += pxa25x.o 7obj-$(CONFIG_PXA25x) += pxa25x.o
8obj-$(CONFIG_PXA27x) += pxa27x.o 8obj-$(CONFIG_PXA27x) += pxa27x.o
9obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o
10obj-$(CONFIG_CPU_PXA300) += pxa300.o
11obj-$(CONFIG_CPU_PXA320) += pxa320.o
9 12
10# Specific board support 13# Specific board support
11obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o 14obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
@@ -20,6 +23,12 @@ obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o
20obj-$(CONFIG_MACH_TOSA) += tosa.o 23obj-$(CONFIG_MACH_TOSA) += tosa.o
21obj-$(CONFIG_MACH_EM_X270) += em-x270.o 24obj-$(CONFIG_MACH_EM_X270) += em-x270.o
22 25
26ifeq ($(CONFIG_MACH_ZYLONITE),y)
27 obj-y += zylonite.o
28 obj-$(CONFIG_CPU_PXA300) += zylonite_pxa300.o
29 obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o
30endif
31
23# Support for blinky lights 32# Support for blinky lights
24led-y := leds.o 33led-y := leds.o
25led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o 34led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index eed95eaf58cd..2263a84844a1 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -51,8 +51,10 @@ unsigned int get_clk_frequency_khz(int info)
51{ 51{
52 if (cpu_is_pxa21x() || cpu_is_pxa25x()) 52 if (cpu_is_pxa21x() || cpu_is_pxa25x())
53 return pxa25x_get_clk_frequency_khz(info); 53 return pxa25x_get_clk_frequency_khz(info);
54 else 54 else if (cpu_is_pxa27x())
55 return pxa27x_get_clk_frequency_khz(info); 55 return pxa27x_get_clk_frequency_khz(info);
56 else
57 return pxa3xx_get_clk_frequency_khz(info);
56} 58}
57EXPORT_SYMBOL(get_clk_frequency_khz); 59EXPORT_SYMBOL(get_clk_frequency_khz);
58 60
@@ -63,8 +65,10 @@ unsigned int get_memclk_frequency_10khz(void)
63{ 65{
64 if (cpu_is_pxa21x() || cpu_is_pxa25x()) 66 if (cpu_is_pxa21x() || cpu_is_pxa25x())
65 return pxa25x_get_memclk_frequency_10khz(); 67 return pxa25x_get_memclk_frequency_10khz();
66 else 68 else if (cpu_is_pxa27x())
67 return pxa27x_get_memclk_frequency_10khz(); 69 return pxa27x_get_memclk_frequency_10khz();
70 else
71 return pxa3xx_get_memclk_frequency_10khz();
68} 72}
69EXPORT_SYMBOL(get_memclk_frequency_10khz); 73EXPORT_SYMBOL(get_memclk_frequency_10khz);
70 74
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 2c4fe617cfc0..b30f240a16c7 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -18,6 +18,7 @@ extern void __init pxa_init_irq_gpio(int gpio_nr);
18extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)); 18extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
19extern void __init pxa25x_init_irq(void); 19extern void __init pxa25x_init_irq(void);
20extern void __init pxa27x_init_irq(void); 20extern void __init pxa27x_init_irq(void);
21extern void __init pxa3xx_init_irq(void);
21extern void __init pxa_map_io(void); 22extern void __init pxa_map_io(void);
22 23
23extern unsigned int get_clk_frequency_khz(int info); 24extern unsigned int get_clk_frequency_khz(int info);
@@ -44,3 +45,10 @@ extern unsigned pxa27x_get_memclk_frequency_10khz(void);
44#define pxa27x_get_memclk_frequency_10khz() (0) 45#define pxa27x_get_memclk_frequency_10khz() (0)
45#endif 46#endif
46 47
48#ifdef CONFIG_PXA3xx
49extern unsigned pxa3xx_get_clk_frequency_khz(int);
50extern unsigned pxa3xx_get_memclk_frequency_10khz(void);
51#else
52#define pxa3xx_get_clk_frequency_khz(x) (0)
53#define pxa3xx_get_memclk_frequency_10khz() (0)
54#endif
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 294cc6758d55..07acb45b16ea 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -65,7 +65,7 @@ void __init pxa_init_irq_low(void)
65 } 65 }
66} 66}
67 67
68#ifdef CONFIG_PXA27x 68#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
69 69
70/* 70/*
71 * This is for the second set of internal IRQs as found on the PXA27x. 71 * This is for the second set of internal IRQs as found on the PXA27x.
diff --git a/arch/arm/mach-pxa/mfp.c b/arch/arm/mach-pxa/mfp.c
new file mode 100644
index 000000000000..5cd3cadbbd10
--- /dev/null
+++ b/arch/arm/mach-pxa/mfp.c
@@ -0,0 +1,235 @@
1/*
2 * linux/arch/arm/mach-pxa/mfp.c
3 *
4 * PXA3xx Multi-Function Pin Support
5 *
6 * Copyright (C) 2007 Marvell Internation Ltd.
7 *
8 * 2007-08-21: eric miao <eric.y.miao@gmail.com>
9 * initial version
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/io.h>
20
21#include <asm/hardware.h>
22#include <asm/arch/mfp.h>
23
24/* mfp_spin_lock is used to ensure that MFP register configuration
25 * (most likely a read-modify-write operation) is atomic, and that
26 * mfp_table[] is consistent
27 */
28static DEFINE_SPINLOCK(mfp_spin_lock);
29
30static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE);
31static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX];
32
33#define mfpr_readl(off) \
34 __raw_readl(mfpr_mmio_base + (off))
35
36#define mfpr_writel(off, val) \
37 __raw_writel(val, mfpr_mmio_base + (off))
38
39/*
40 * perform a read-back of any MFPR register to make sure the
41 * previous writings are finished
42 */
43#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0)
44
45static inline void __mfp_config(int pin, unsigned long val)
46{
47 unsigned long off = mfp_table[pin].mfpr_off;
48
49 mfp_table[pin].mfpr_val = val;
50 mfpr_writel(off, val);
51}
52
53void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num)
54{
55 int i, pin;
56 unsigned long val, flags;
57 mfp_cfg_t *mfp_cfg = mfp_cfgs;
58
59 spin_lock_irqsave(&mfp_spin_lock, flags);
60
61 for (i = 0; i < num; i++, mfp_cfg++) {
62 pin = MFP_CFG_PIN(*mfp_cfg);
63 val = MFP_CFG_VAL(*mfp_cfg);
64
65 BUG_ON(pin >= MFP_PIN_MAX);
66
67 __mfp_config(pin, val);
68 }
69
70 mfpr_sync();
71 spin_unlock_irqrestore(&mfp_spin_lock, flags);
72}
73
74unsigned long pxa3xx_mfp_read(int mfp)
75{
76 unsigned long val, flags;
77
78 BUG_ON(mfp >= MFP_PIN_MAX);
79
80 spin_lock_irqsave(&mfp_spin_lock, flags);
81 val = mfpr_readl(mfp_table[mfp].mfpr_off);
82 spin_unlock_irqrestore(&mfp_spin_lock, flags);
83
84 return val;
85}
86
87void pxa3xx_mfp_write(int mfp, unsigned long val)
88{
89 unsigned long flags;
90
91 BUG_ON(mfp >= MFP_PIN_MAX);
92
93 spin_lock_irqsave(&mfp_spin_lock, flags);
94 mfpr_writel(mfp_table[mfp].mfpr_off, val);
95 mfpr_sync();
96 spin_unlock_irqrestore(&mfp_spin_lock, flags);
97}
98
99void pxa3xx_mfp_set_afds(int mfp, int af, int ds)
100{
101 uint32_t mfpr_off, mfpr_val;
102 unsigned long flags;
103
104 BUG_ON(mfp >= MFP_PIN_MAX);
105
106 spin_lock_irqsave(&mfp_spin_lock, flags);
107 mfpr_off = mfp_table[mfp].mfpr_off;
108
109 mfpr_val = mfpr_readl(mfpr_off);
110 mfpr_val &= ~(MFPR_AF_MASK | MFPR_DRV_MASK);
111 mfpr_val |= (((af & 0x7) << MFPR_ALT_OFFSET) |
112 ((ds & 0x7) << MFPR_DRV_OFFSET));
113
114 mfpr_writel(mfpr_off, mfpr_val);
115 mfpr_sync();
116
117 spin_unlock_irqrestore(&mfp_spin_lock, flags);
118}
119
120void pxa3xx_mfp_set_rdh(int mfp, int rdh)
121{
122 uint32_t mfpr_off, mfpr_val;
123 unsigned long flags;
124
125 BUG_ON(mfp >= MFP_PIN_MAX);
126
127 spin_lock_irqsave(&mfp_spin_lock, flags);
128
129 mfpr_off = mfp_table[mfp].mfpr_off;
130
131 mfpr_val = mfpr_readl(mfpr_off);
132 mfpr_val &= ~MFPR_RDH_MASK;
133
134 if (likely(rdh))
135 mfpr_val |= (1u << MFPR_SS_OFFSET);
136
137 mfpr_writel(mfpr_off, mfpr_val);
138 mfpr_sync();
139
140 spin_unlock_irqrestore(&mfp_spin_lock, flags);
141}
142
143void pxa3xx_mfp_set_lpm(int mfp, int lpm)
144{
145 uint32_t mfpr_off, mfpr_val;
146 unsigned long flags;
147
148 BUG_ON(mfp >= MFP_PIN_MAX);
149
150 spin_lock_irqsave(&mfp_spin_lock, flags);
151
152 mfpr_off = mfp_table[mfp].mfpr_off;
153 mfpr_val = mfpr_readl(mfpr_off);
154 mfpr_val &= ~MFPR_LPM_MASK;
155
156 if (lpm & 0x1) mfpr_val |= 1u << MFPR_SON_OFFSET;
157 if (lpm & 0x2) mfpr_val |= 1u << MFPR_SD_OFFSET;
158 if (lpm & 0x4) mfpr_val |= 1u << MFPR_PU_OFFSET;
159 if (lpm & 0x8) mfpr_val |= 1u << MFPR_PD_OFFSET;
160 if (lpm &0x10) mfpr_val |= 1u << MFPR_PS_OFFSET;
161
162 mfpr_writel(mfpr_off, mfpr_val);
163 mfpr_sync();
164
165 spin_unlock_irqrestore(&mfp_spin_lock, flags);
166}
167
168void pxa3xx_mfp_set_pull(int mfp, int pull)
169{
170 uint32_t mfpr_off, mfpr_val;
171 unsigned long flags;
172
173 BUG_ON(mfp >= MFP_PIN_MAX);
174
175 spin_lock_irqsave(&mfp_spin_lock, flags);
176
177 mfpr_off = mfp_table[mfp].mfpr_off;
178 mfpr_val = mfpr_readl(mfpr_off);
179 mfpr_val &= ~MFPR_PULL_MASK;
180 mfpr_val |= ((pull & 0x7u) << MFPR_PD_OFFSET);
181
182 mfpr_writel(mfpr_off, mfpr_val);
183 mfpr_sync();
184
185 spin_unlock_irqrestore(&mfp_spin_lock, flags);
186}
187
188void pxa3xx_mfp_set_edge(int mfp, int edge)
189{
190 uint32_t mfpr_off, mfpr_val;
191 unsigned long flags;
192
193 BUG_ON(mfp >= MFP_PIN_MAX);
194
195 spin_lock_irqsave(&mfp_spin_lock, flags);
196
197 mfpr_off = mfp_table[mfp].mfpr_off;
198 mfpr_val = mfpr_readl(mfpr_off);
199
200 mfpr_val &= ~MFPR_EDGE_MASK;
201 mfpr_val |= (edge & 0x3u) << MFPR_ERE_OFFSET;
202 mfpr_val |= (!edge & 0x1) << MFPR_EC_OFFSET;
203
204 mfpr_writel(mfpr_off, mfpr_val);
205 mfpr_sync();
206
207 spin_unlock_irqrestore(&mfp_spin_lock, flags);
208}
209
210void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map)
211{
212 struct pxa3xx_mfp_addr_map *p;
213 unsigned long offset, flags;
214 int i;
215
216 spin_lock_irqsave(&mfp_spin_lock, flags);
217
218 for (p = map; p->start != MFP_PIN_INVALID; p++) {
219 offset = p->offset;
220 i = p->start;
221
222 do {
223 mfp_table[i].mfpr_off = offset;
224 mfp_table[i].mfpr_val = 0;
225 offset += 4; i++;
226 } while ((i <= p->end) && (p->end != -1));
227 }
228
229 spin_unlock_irqrestore(&mfp_spin_lock, flags);
230}
231
232void __init pxa3xx_init_mfp(void)
233{
234 memset(mfp_table, 0, sizeof(mfp_table));
235}
diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c
new file mode 100644
index 000000000000..5363b1322652
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa300.c
@@ -0,0 +1,93 @@
1/*
2 * linux/arch/arm/mach-pxa/pxa300.c
3 *
4 * Code specific to PXA300/PXA310
5 *
6 * Copyright (C) 2007 Marvell Internation Ltd.
7 *
8 * 2007-08-21: eric miao <eric.y.miao@gmail.com>
9 * initial version
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18
19#include <asm/hardware.h>
20#include <asm/arch/mfp-pxa300.h>
21
22static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = {
23
24 MFP_ADDR_X(GPIO0, GPIO2, 0x00b4),
25 MFP_ADDR_X(GPIO3, GPIO26, 0x027c),
26 MFP_ADDR_X(GPIO27, GPIO127, 0x0400),
27 MFP_ADDR_X(GPIO0_2, GPIO6_2, 0x02ec),
28
29 MFP_ADDR(nBE0, 0x0204),
30 MFP_ADDR(nBE1, 0x0208),
31
32 MFP_ADDR(nLUA, 0x0244),
33 MFP_ADDR(nLLA, 0x0254),
34
35 MFP_ADDR(DF_CLE_nOE, 0x0240),
36 MFP_ADDR(DF_nRE_nOE, 0x0200),
37 MFP_ADDR(DF_ALE_nWE, 0x020C),
38 MFP_ADDR(DF_INT_RnB, 0x00C8),
39 MFP_ADDR(DF_nCS0, 0x0248),
40 MFP_ADDR(DF_nCS1, 0x0278),
41 MFP_ADDR(DF_nWE, 0x00CC),
42
43 MFP_ADDR(DF_ADDR0, 0x0210),
44 MFP_ADDR(DF_ADDR1, 0x0214),
45 MFP_ADDR(DF_ADDR2, 0x0218),
46 MFP_ADDR(DF_ADDR3, 0x021C),
47
48 MFP_ADDR(DF_IO0, 0x0220),
49 MFP_ADDR(DF_IO1, 0x0228),
50 MFP_ADDR(DF_IO2, 0x0230),
51 MFP_ADDR(DF_IO3, 0x0238),
52 MFP_ADDR(DF_IO4, 0x0258),
53 MFP_ADDR(DF_IO5, 0x0260),
54 MFP_ADDR(DF_IO6, 0x0268),
55 MFP_ADDR(DF_IO7, 0x0270),
56 MFP_ADDR(DF_IO8, 0x0224),
57 MFP_ADDR(DF_IO9, 0x022C),
58 MFP_ADDR(DF_IO10, 0x0234),
59 MFP_ADDR(DF_IO11, 0x023C),
60 MFP_ADDR(DF_IO12, 0x025C),
61 MFP_ADDR(DF_IO13, 0x0264),
62 MFP_ADDR(DF_IO14, 0x026C),
63 MFP_ADDR(DF_IO15, 0x0274),
64
65 MFP_ADDR_END,
66};
67
68/* override pxa300 MFP register addresses */
69static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = {
70 MFP_ADDR_X(GPIO30, GPIO98, 0x0418),
71 MFP_ADDR_X(GPIO7_2, GPIO12_2, 0x052C),
72
73 MFP_ADDR(ULPI_STP, 0x040C),
74 MFP_ADDR(ULPI_NXT, 0x0410),
75 MFP_ADDR(ULPI_DIR, 0x0414),
76
77 MFP_ADDR_END,
78};
79
80static int __init pxa300_init(void)
81{
82 if (cpu_is_pxa300() || cpu_is_pxa310()) {
83 pxa3xx_init_mfp();
84 pxa3xx_mfp_init_addr(pxa300_mfp_addr_map);
85 }
86
87 if (cpu_is_pxa310())
88 pxa3xx_mfp_init_addr(pxa310_mfp_addr_map);
89
90 return 0;
91}
92
93core_initcall(pxa300_init);
diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c
new file mode 100644
index 000000000000..cd9eba5b3df9
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa320.c
@@ -0,0 +1,88 @@
1/*
2 * linux/arch/arm/mach-pxa/pxa320.c
3 *
4 * Code specific to PXA320
5 *
6 * Copyright (C) 2007 Marvell Internation Ltd.
7 *
8 * 2007-08-21: eric miao <eric.y.miao@gmail.com>
9 * initial version
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18
19#include <asm/hardware.h>
20#include <asm/arch/mfp.h>
21#include <asm/arch/mfp-pxa320.h>
22
23static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
24
25 MFP_ADDR_X(GPIO0, GPIO4, 0x0124),
26 MFP_ADDR_X(GPIO5, GPIO26, 0x028C),
27 MFP_ADDR_X(GPIO27, GPIO62, 0x0400),
28 MFP_ADDR_X(GPIO63, GPIO73, 0x04B4),
29 MFP_ADDR_X(GPIO74, GPIO98, 0x04F0),
30 MFP_ADDR_X(GPIO99, GPIO127, 0x0600),
31 MFP_ADDR_X(GPIO0_2, GPIO5_2, 0x0674),
32 MFP_ADDR_X(GPIO6_2, GPIO13_2, 0x0494),
33 MFP_ADDR_X(GPIO14_2, GPIO17_2, 0x04E0),
34
35 MFP_ADDR(nXCVREN, 0x0138),
36 MFP_ADDR(DF_CLE_nOE, 0x0204),
37 MFP_ADDR(DF_nADV1_ALE, 0x0208),
38 MFP_ADDR(DF_SCLK_S, 0x020C),
39 MFP_ADDR(DF_SCLK_E, 0x0210),
40 MFP_ADDR(nBE0, 0x0214),
41 MFP_ADDR(nBE1, 0x0218),
42 MFP_ADDR(DF_nADV2_ALE, 0x021C),
43 MFP_ADDR(DF_INT_RnB, 0x0220),
44 MFP_ADDR(DF_nCS0, 0x0224),
45 MFP_ADDR(DF_nCS1, 0x0228),
46 MFP_ADDR(DF_nWE, 0x022C),
47 MFP_ADDR(DF_nRE_nOE, 0x0230),
48 MFP_ADDR(nLUA, 0x0234),
49 MFP_ADDR(nLLA, 0x0238),
50 MFP_ADDR(DF_ADDR0, 0x023C),
51 MFP_ADDR(DF_ADDR1, 0x0240),
52 MFP_ADDR(DF_ADDR2, 0x0244),
53 MFP_ADDR(DF_ADDR3, 0x0248),
54 MFP_ADDR(DF_IO0, 0x024C),
55 MFP_ADDR(DF_IO8, 0x0250),
56 MFP_ADDR(DF_IO1, 0x0254),
57 MFP_ADDR(DF_IO9, 0x0258),
58 MFP_ADDR(DF_IO2, 0x025C),
59 MFP_ADDR(DF_IO10, 0x0260),
60 MFP_ADDR(DF_IO3, 0x0264),
61 MFP_ADDR(DF_IO11, 0x0268),
62 MFP_ADDR(DF_IO4, 0x026C),
63 MFP_ADDR(DF_IO12, 0x0270),
64 MFP_ADDR(DF_IO5, 0x0274),
65 MFP_ADDR(DF_IO13, 0x0278),
66 MFP_ADDR(DF_IO6, 0x027C),
67 MFP_ADDR(DF_IO14, 0x0280),
68 MFP_ADDR(DF_IO7, 0x0284),
69 MFP_ADDR(DF_IO15, 0x0288),
70
71 MFP_ADDR_END,
72};
73
74static void __init pxa320_init_mfp(void)
75{
76 pxa3xx_init_mfp();
77 pxa3xx_mfp_init_addr(pxa320_mfp_addr_map);
78}
79
80static int __init pxa320_init(void)
81{
82 if (cpu_is_pxa320())
83 pxa320_init_mfp();
84
85 return 0;
86}
87
88core_initcall(pxa320_init);
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
new file mode 100644
index 000000000000..39f0de8c189e
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -0,0 +1,216 @@
1/*
2 * linux/arch/arm/mach-pxa/pxa3xx.c
3 *
4 * code specific to pxa3xx aka Monahans
5 *
6 * Copyright (C) 2006 Marvell International Ltd.
7 *
8 * 2007-09-02: eric miao <eric.y.miao@gmail.com>
9 * initial version
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/pm.h>
20#include <linux/platform_device.h>
21#include <linux/irq.h>
22
23#include <asm/hardware.h>
24#include <asm/arch/pxa3xx-regs.h>
25#include <asm/arch/ohci.h>
26#include <asm/arch/pm.h>
27#include <asm/arch/dma.h>
28#include <asm/arch/ssp.h>
29
30#include "generic.h"
31#include "devices.h"
32#include "clock.h"
33
34/* Crystal clock: 13MHz */
35#define BASE_CLK 13000000
36
37/* Ring Oscillator Clock: 60MHz */
38#define RO_CLK 60000000
39
40#define ACCR_D0CS (1 << 26)
41
42/* crystal frequency to static memory controller multiplier (SMCFS) */
43static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
44
45/* crystal frequency to HSIO bus frequency multiplier (HSS) */
46static unsigned char hss_mult[4] = { 8, 12, 16, 0 };
47
48/*
49 * Get the clock frequency as reflected by CCSR and the turbo flag.
50 * We assume these values have been applied via a fcs.
51 * If info is not 0 we also display the current settings.
52 */
53unsigned int pxa3xx_get_clk_frequency_khz(int info)
54{
55 unsigned long acsr, xclkcfg;
56 unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS;
57
58 /* Read XCLKCFG register turbo bit */
59 __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg));
60 t = xclkcfg & 0x1;
61
62 acsr = ACSR;
63
64 xl = acsr & 0x1f;
65 xn = (acsr >> 8) & 0x7;
66 hss = (acsr >> 14) & 0x3;
67
68 XL = xl * BASE_CLK;
69 XN = xn * XL;
70
71 ro = acsr & ACCR_D0CS;
72
73 CLK = (ro) ? RO_CLK : ((t) ? XN : XL);
74 HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK;
75
76 if (info) {
77 pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n",
78 RO_CLK / 1000000, (RO_CLK % 1000000) / 10000,
79 (ro) ? "" : "in");
80 pr_info("Run Mode clock: %d.%02dMHz (*%d)\n",
81 XL / 1000000, (XL % 1000000) / 10000, xl);
82 pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n",
83 XN / 1000000, (XN % 1000000) / 10000, xn,
84 (t) ? "" : "in");
85 pr_info("HSIO bus clock: %d.%02dMHz\n",
86 HSS / 1000000, (HSS % 1000000) / 10000);
87 }
88
89 return CLK;
90}
91
92/*
93 * Return the current static memory controller clock frequency
94 * in units of 10kHz
95 */
96unsigned int pxa3xx_get_memclk_frequency_10khz(void)
97{
98 unsigned long acsr;
99 unsigned int smcfs, clk = 0;
100
101 acsr = ACSR;
102
103 smcfs = (acsr >> 23) & 0x7;
104 clk = (acsr & ACCR_D0CS) ? RO_CLK : smcfs_mult[smcfs] * BASE_CLK;
105
106 return (clk / 10000);
107}
108
109/*
110 * Return the current HSIO bus clock frequency
111 */
112static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk)
113{
114 unsigned long acsr;
115 unsigned int hss, hsio_clk;
116
117 acsr = ACSR;
118
119 hss = (acsr >> 14) & 0x3;
120 hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK;
121
122 return hsio_clk;
123}
124
125static void clk_pxa3xx_cken_enable(struct clk *clk)
126{
127 unsigned long mask = 1ul << (clk->cken & 0x1f);
128
129 local_irq_disable();
130
131 if (clk->cken < 32)
132 CKENA |= mask;
133 else
134 CKENB |= mask;
135
136 local_irq_enable();
137}
138
139static void clk_pxa3xx_cken_disable(struct clk *clk)
140{
141 unsigned long mask = 1ul << (clk->cken & 0x1f);
142
143 local_irq_disable();
144
145 if (clk->cken < 32)
146 CKENA &= ~mask;
147 else
148 CKENB &= ~mask;
149
150 local_irq_enable();
151}
152
153static const struct clkops clk_pxa3xx_hsio_ops = {
154 .enable = clk_pxa3xx_cken_enable,
155 .disable = clk_pxa3xx_cken_disable,
156 .getrate = clk_pxa3xx_hsio_getrate,
157};
158
159static struct clk pxa3xx_clks[] = {
160 INIT_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev),
161 INIT_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL),
162
163 INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
164 INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
165 INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL),
166
167 INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev),
168 INIT_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev),
169};
170
171void __init pxa3xx_init_irq(void)
172{
173 /* enable CP6 access */
174 u32 value;
175 __asm__ __volatile__("mrc p15, 0, %0, c15, c1, 0\n": "=r"(value));
176 value |= (1 << 6);
177 __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
178
179 pxa_init_irq_low();
180 pxa_init_irq_high();
181 pxa_init_irq_gpio(128);
182}
183
184/*
185 * device registration specific to PXA3xx.
186 */
187
188static struct platform_device *devices[] __initdata = {
189 &pxa_device_mci,
190 &pxa_device_udc,
191 &pxa_device_fb,
192 &pxa_device_ffuart,
193 &pxa_device_btuart,
194 &pxa_device_stuart,
195 &pxa_device_i2c,
196 &pxa_device_i2s,
197 &pxa_device_ficp,
198 &pxa_device_rtc,
199};
200
201static int __init pxa3xx_init(void)
202{
203 int ret = 0;
204
205 if (cpu_is_pxa3xx()) {
206 clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks));
207
208 if ((ret = pxa_init_dma(32)))
209 return ret;
210
211 return platform_add_devices(devices, ARRAY_SIZE(devices));
212 }
213 return 0;
214}
215
216subsys_initcall(pxa3xx_init);
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
new file mode 100644
index 000000000000..3f18d760dd1b
--- /dev/null
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -0,0 +1,184 @@
1/*
2 * linux/arch/arm/mach-pxa/zylonite.c
3 *
4 * Support for the PXA3xx Development Platform (aka Zylonite)
5 *
6 * Copyright (C) 2006 Marvell International Ltd.
7 *
8 * 2007-09-04: eric miao <eric.y.miao@gmail.com>
9 * rewrite to align with latest kernel
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/interrupt.h>
19#include <linux/init.h>
20#include <linux/platform_device.h>
21
22#include <asm/mach-types.h>
23#include <asm/mach/arch.h>
24#include <asm/hardware.h>
25#include <asm/arch/gpio.h>
26#include <asm/arch/pxafb.h>
27#include <asm/arch/zylonite.h>
28
29#include "generic.h"
30
31int gpio_backlight;
32int gpio_eth_irq;
33
34int lcd_id;
35int lcd_orientation;
36
37static struct resource smc91x_resources[] = {
38 [0] = {
39 .start = ZYLONITE_ETH_PHYS + 0x300,
40 .end = ZYLONITE_ETH_PHYS + 0xfffff,
41 .flags = IORESOURCE_MEM,
42 },
43 [1] = {
44 .start = -1, /* for run-time assignment */
45 .end = -1,
46 .flags = IORESOURCE_IRQ,
47 }
48};
49
50static struct platform_device smc91x_device = {
51 .name = "smc91x",
52 .id = 0,
53 .num_resources = ARRAY_SIZE(smc91x_resources),
54 .resource = smc91x_resources,
55};
56
57#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES)
58static void zylonite_backlight_power(int on)
59{
60 gpio_set_value(gpio_backlight, on);
61}
62
63static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
64 .pixclock = 110000,
65 .xres = 240,
66 .yres = 320,
67 .bpp = 16,
68 .hsync_len = 4,
69 .left_margin = 6,
70 .right_margin = 4,
71 .vsync_len = 2,
72 .upper_margin = 2,
73 .lower_margin = 3,
74 .sync = FB_SYNC_VERT_HIGH_ACT,
75};
76
77static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
78 .pixclock = 50000,
79 .xres = 640,
80 .yres = 480,
81 .bpp = 16,
82 .hsync_len = 1,
83 .left_margin = 0x9f,
84 .right_margin = 1,
85 .vsync_len = 44,
86 .upper_margin = 0,
87 .lower_margin = 0,
88 .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
89};
90
91static struct pxafb_mach_info zylonite_toshiba_lcd_info = {
92 .num_modes = 1,
93 .lccr0 = LCCR0_Act,
94 .lccr3 = LCCR3_PCP,
95 .pxafb_backlight_power = zylonite_backlight_power,
96};
97
98static struct pxafb_mode_info sharp_ls037_modes[] = {
99 [0] = {
100 .pixclock = 158000,
101 .xres = 240,
102 .yres = 320,
103 .bpp = 16,
104 .hsync_len = 4,
105 .left_margin = 39,
106 .right_margin = 39,
107 .vsync_len = 1,
108 .upper_margin = 2,
109 .lower_margin = 3,
110 .sync = 0,
111 },
112 [1] = {
113 .pixclock = 39700,
114 .xres = 480,
115 .yres = 640,
116 .bpp = 16,
117 .hsync_len = 8,
118 .left_margin = 81,
119 .right_margin = 81,
120 .vsync_len = 1,
121 .upper_margin = 2,
122 .lower_margin = 7,
123 .sync = 0,
124 },
125};
126
127static struct pxafb_mach_info zylonite_sharp_lcd_info = {
128 .modes = sharp_ls037_modes,
129 .num_modes = 2,
130 .lccr0 = LCCR0_Act,
131 .lccr3 = LCCR3_PCP | LCCR3_HSP | LCCR3_VSP,
132 .pxafb_backlight_power = zylonite_backlight_power,
133};
134
135static void __init zylonite_init_lcd(void)
136{
137 /* backlight GPIO: output, default on */
138 gpio_direction_output(gpio_backlight, 1);
139
140 if (lcd_id & 0x20) {
141 set_pxa_fb_info(&zylonite_sharp_lcd_info);
142 return;
143 }
144
145 /* legacy LCD panels, it would be handy here if LCD panel type can
146 * be decided at run-time
147 */
148 if (1)
149 zylonite_toshiba_lcd_info.modes = &toshiba_ltm035a776c_mode;
150 else
151 zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode;
152
153 set_pxa_fb_info(&zylonite_toshiba_lcd_info);
154}
155#else
156static inline void zylonite_init_lcd(void) {}
157#endif
158
159static void __init zylonite_init(void)
160{
161 /* board-processor specific initialization */
162 zylonite_pxa300_init();
163 zylonite_pxa320_init();
164
165 /*
166 * Note: We depend that the bootloader set
167 * the correct value to MSC register for SMC91x.
168 */
169 smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq);
170 smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq);
171 platform_device_register(&smc91x_device);
172
173 zylonite_init_lcd();
174}
175
176MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
177 .phys_io = 0x40000000,
178 .boot_params = 0xa0000100,
179 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
180 .map_io = pxa_map_io,
181 .init_irq = pxa3xx_init_irq,
182 .timer = &pxa_timer,
183 .init_machine = zylonite_init,
184MACHINE_END
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
new file mode 100644
index 000000000000..b5fbd2f4c693
--- /dev/null
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -0,0 +1,188 @@
1/*
2 * linux/arch/arm/mach-pxa/zylonite_pxa300.c
3 *
4 * PXA300/PXA310 specific support code for the
5 * PXA3xx Development Platform (aka Zylonite)
6 *
7 * Copyright (C) 2007 Marvell Internation Ltd.
8 * 2007-08-21: eric miao <eric.y.miao@gmail.com>
9 * initial version
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19
20#include <asm/gpio.h>
21#include <asm/arch/mfp-pxa300.h>
22#include <asm/arch/zylonite.h>
23
24#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
25
26/* PXA300/PXA310 common configurations */
27static mfp_cfg_t common_mfp_cfg[] __initdata = {
28 /* LCD */
29 GPIO54_LCD_LDD_0,
30 GPIO55_LCD_LDD_1,
31 GPIO56_LCD_LDD_2,
32 GPIO57_LCD_LDD_3,
33 GPIO58_LCD_LDD_4,
34 GPIO59_LCD_LDD_5,
35 GPIO60_LCD_LDD_6,
36 GPIO61_LCD_LDD_7,
37 GPIO62_LCD_LDD_8,
38 GPIO63_LCD_LDD_9,
39 GPIO64_LCD_LDD_10,
40 GPIO65_LCD_LDD_11,
41 GPIO66_LCD_LDD_12,
42 GPIO67_LCD_LDD_13,
43 GPIO68_LCD_LDD_14,
44 GPIO69_LCD_LDD_15,
45 GPIO70_LCD_LDD_16,
46 GPIO71_LCD_LDD_17,
47 GPIO72_LCD_FCLK,
48 GPIO73_LCD_LCLK,
49 GPIO74_LCD_PCLK,
50 GPIO75_LCD_BIAS,
51 GPIO76_LCD_VSYNC,
52 GPIO127_LCD_CS_N,
53
54 /* BTUART */
55 GPIO111_UART2_RTS,
56 GPIO112_UART2_RXD,
57 GPIO113_UART2_TXD,
58 GPIO114_UART2_CTS,
59
60 /* STUART */
61 GPIO109_UART3_TXD,
62 GPIO110_UART3_RXD,
63
64 /* AC97 */
65 GPIO23_AC97_nACRESET,
66 GPIO24_AC97_SYSCLK,
67 GPIO29_AC97_BITCLK,
68 GPIO25_AC97_SDATA_IN_0,
69 GPIO27_AC97_SDATA_OUT,
70 GPIO28_AC97_SYNC,
71
72 /* Keypad */
73 GPIO107_KP_DKIN_0,
74 GPIO108_KP_DKIN_1,
75 GPIO115_KP_MKIN_0,
76 GPIO116_KP_MKIN_1,
77 GPIO117_KP_MKIN_2,
78 GPIO118_KP_MKIN_3,
79 GPIO119_KP_MKIN_4,
80 GPIO120_KP_MKIN_5,
81 GPIO2_2_KP_MKIN_6,
82 GPIO3_2_KP_MKIN_7,
83 GPIO121_KP_MKOUT_0,
84 GPIO122_KP_MKOUT_1,
85 GPIO123_KP_MKOUT_2,
86 GPIO124_KP_MKOUT_3,
87 GPIO125_KP_MKOUT_4,
88 GPIO4_2_KP_MKOUT_5,
89 GPIO5_2_KP_MKOUT_6,
90 GPIO6_2_KP_MKOUT_7,
91};
92
93static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
94 /* FFUART */
95 GPIO30_UART1_RXD,
96 GPIO31_UART1_TXD,
97 GPIO32_UART1_CTS,
98 GPIO37_UART1_RTS,
99 GPIO33_UART1_DCD,
100 GPIO34_UART1_DSR,
101 GPIO35_UART1_RI,
102 GPIO36_UART1_DTR,
103
104 /* Ethernet */
105 GPIO2_nCS3,
106 GPIO99_GPIO,
107};
108
109static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
110 /* FFUART */
111 GPIO99_UART1_RXD,
112 GPIO100_UART1_TXD,
113 GPIO101_UART1_CTS,
114 GPIO106_UART1_RTS,
115
116 /* Ethernet */
117 GPIO2_nCS3,
118 GPIO102_GPIO,
119};
120
121#define NUM_LCD_DETECT_PINS 7
122
123static int lcd_detect_pins[] __initdata = {
124 MFP_PIN_GPIO71, /* LCD_LDD_17 - ORIENT */
125 MFP_PIN_GPIO70, /* LCD_LDD_16 - LCDID[5] */
126 MFP_PIN_GPIO75, /* LCD_BIAS - LCDID[4] */
127 MFP_PIN_GPIO73, /* LCD_LCLK - LCDID[3] */
128 MFP_PIN_GPIO72, /* LCD_FCLK - LCDID[2] */
129 MFP_PIN_GPIO127,/* LCD_CS_N - LCDID[1] */
130 MFP_PIN_GPIO76, /* LCD_VSYNC - LCDID[0] */
131};
132
133static void __init zylonite_detect_lcd_panel(void)
134{
135 unsigned long mfpr_save[NUM_LCD_DETECT_PINS];
136 int i, gpio, id = 0;
137
138 /* save the original MFP settings of these pins and configure
139 * them as GPIO Input, DS01X, Pull Neither, Edge Clear
140 */
141 for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
142 mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]);
143 pxa3xx_mfp_write(lcd_detect_pins[i], 0x8440);
144 }
145
146 for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
147 id = id << 1;
148 gpio = mfp_to_gpio(lcd_detect_pins[i]);
149 gpio_direction_input(gpio);
150
151 if (gpio_get_value(gpio))
152 id = id | 0x1;
153 }
154
155 /* lcd id, flush out bit 1 */
156 lcd_id = id & 0x3d;
157
158 /* lcd orientation, portrait or landscape */
159 lcd_orientation = (id >> 6) & 0x1;
160
161 /* restore the original MFP settings */
162 for (i = 0; i < NUM_LCD_DETECT_PINS; i++)
163 pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
164}
165
166void __init zylonite_pxa300_init(void)
167{
168 if (cpu_is_pxa300() || cpu_is_pxa310()) {
169 /* initialize MFP */
170 pxa3xx_mfp_config(ARRAY_AND_SIZE(common_mfp_cfg));
171
172 /* detect LCD panel */
173 zylonite_detect_lcd_panel();
174
175 /* GPIO pin assignment */
176 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20);
177 }
178
179 if (cpu_is_pxa300()) {
180 pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa300_mfp_cfg));
181 gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO99);
182 }
183
184 if (cpu_is_pxa310()) {
185 pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg));
186 gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102);
187 }
188}
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c
new file mode 100644
index 000000000000..63cb36be086b
--- /dev/null
+++ b/arch/arm/mach-pxa/zylonite_pxa320.c
@@ -0,0 +1,173 @@
1/*
2 * linux/arch/arm/mach-pxa/zylonite_pxa320.c
3 *
4 * PXA320 specific support code for the
5 * PXA3xx Development Platform (aka Zylonite)
6 *
7 * Copyright (C) 2007 Marvell Internation Ltd.
8 * 2007-08-21: eric miao <eric.y.miao@gmail.com>
9 * initial version
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19
20#include <asm/arch/gpio.h>
21#include <asm/arch/mfp-pxa320.h>
22#include <asm/arch/zylonite.h>
23
24#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
25
26static mfp_cfg_t mfp_cfg[] __initdata = {
27 /* LCD */
28 GPIO6_2_LCD_LDD_0,
29 GPIO7_2_LCD_LDD_1,
30 GPIO8_2_LCD_LDD_2,
31 GPIO9_2_LCD_LDD_3,
32 GPIO10_2_LCD_LDD_4,
33 GPIO11_2_LCD_LDD_5,
34 GPIO12_2_LCD_LDD_6,
35 GPIO13_2_LCD_LDD_7,
36 GPIO63_LCD_LDD_8,
37 GPIO64_LCD_LDD_9,
38 GPIO65_LCD_LDD_10,
39 GPIO66_LCD_LDD_11,
40 GPIO67_LCD_LDD_12,
41 GPIO68_LCD_LDD_13,
42 GPIO69_LCD_LDD_14,
43 GPIO70_LCD_LDD_15,
44 GPIO71_LCD_LDD_16,
45 GPIO72_LCD_LDD_17,
46 GPIO73_LCD_CS_N,
47 GPIO74_LCD_VSYNC,
48 GPIO14_2_LCD_FCLK,
49 GPIO15_2_LCD_LCLK,
50 GPIO16_2_LCD_PCLK,
51 GPIO17_2_LCD_BIAS,
52
53 /* FFUART */
54 GPIO41_UART1_RXD,
55 GPIO42_UART1_TXD,
56 GPIO43_UART1_CTS,
57 GPIO44_UART1_DCD,
58 GPIO45_UART1_DSR,
59 GPIO46_UART1_RI,
60 GPIO47_UART1_DTR,
61 GPIO48_UART1_RTS,
62
63 /* AC97 */
64 GPIO34_AC97_SYSCLK,
65 GPIO35_AC97_SDATA_IN_0,
66 GPIO37_AC97_SDATA_OUT,
67 GPIO38_AC97_SYNC,
68 GPIO39_AC97_BITCLK,
69 GPIO40_AC97_nACRESET,
70
71 /* I2C */
72 GPIO32_I2C_SCL,
73 GPIO33_I2C_SDA,
74
75 /* Keypad */
76 GPIO105_KP_DKIN_0,
77 GPIO106_KP_DKIN_1,
78 GPIO113_KP_MKIN_0,
79 GPIO114_KP_MKIN_1,
80 GPIO115_KP_MKIN_2,
81 GPIO116_KP_MKIN_3,
82 GPIO117_KP_MKIN_4,
83 GPIO118_KP_MKIN_5,
84 GPIO119_KP_MKIN_6,
85 GPIO120_KP_MKIN_7,
86 GPIO121_KP_MKOUT_0,
87 GPIO122_KP_MKOUT_1,
88 GPIO123_KP_MKOUT_2,
89 GPIO124_KP_MKOUT_3,
90 GPIO125_KP_MKOUT_4,
91 GPIO126_KP_MKOUT_5,
92 GPIO127_KP_MKOUT_6,
93 GPIO5_2_KP_MKOUT_7,
94
95 /* Ethernet */
96 GPIO4_nCS3,
97 GPIO90_GPIO,
98};
99
100#define NUM_LCD_DETECT_PINS 7
101
102static int lcd_detect_pins[] __initdata = {
103 MFP_PIN_GPIO72, /* LCD_LDD_17 - ORIENT */
104 MFP_PIN_GPIO71, /* LCD_LDD_16 - LCDID[5] */
105 MFP_PIN_GPIO17_2, /* LCD_BIAS - LCDID[4] */
106 MFP_PIN_GPIO15_2, /* LCD_LCLK - LCDID[3] */
107 MFP_PIN_GPIO14_2, /* LCD_FCLK - LCDID[2] */
108 MFP_PIN_GPIO73, /* LCD_CS_N - LCDID[1] */
109 MFP_PIN_GPIO74, /* LCD_VSYNC - LCDID[0] */
110 /*
111 * set the MFP_PIN_GPIO 14/15/17 to alternate function other than
112 * GPIO to avoid input level confliction with 14_2, 15_2, 17_2
113 */
114 MFP_PIN_GPIO14,
115 MFP_PIN_GPIO15,
116 MFP_PIN_GPIO17,
117};
118
119static int lcd_detect_mfpr[] __initdata = {
120 /* AF0, DS 1X, Pull Neither, Edge Clear */
121 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440,
122 0xc442, /* Backlight, Pull-Up, AF2 */
123 0x8445, /* AF5 */
124 0x8445, /* AF5 */
125};
126
127static void __init zylonite_detect_lcd_panel(void)
128{
129 unsigned long mfpr_save[ARRAY_SIZE(lcd_detect_pins)];
130 int i, gpio, id = 0;
131
132 /* save the original MFP settings of these pins and configure them
133 * as GPIO Input, DS01X, Pull Neither, Edge Clear
134 */
135 for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++) {
136 mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]);
137 pxa3xx_mfp_write(lcd_detect_pins[i], lcd_detect_mfpr[i]);
138 }
139
140 for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
141 id = id << 1;
142 gpio = mfp_to_gpio(lcd_detect_pins[i]);
143 gpio_direction_input(gpio);
144
145 if (gpio_get_value(gpio))
146 id = id | 0x1;
147 }
148
149 /* lcd id, flush out bit 1 */
150 lcd_id = id & 0x3d;
151
152 /* lcd orientation, portrait or landscape */
153 lcd_orientation = (id >> 6) & 0x1;
154
155 /* restore the original MFP settings */
156 for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++)
157 pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
158}
159
160void __init zylonite_pxa320_init(void)
161{
162 if (cpu_is_pxa320()) {
163 /* initialize MFP */
164 pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_cfg));
165
166 /* detect LCD panel */
167 zylonite_detect_lcd_panel();
168
169 /* GPIO pin assignment */
170 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14);
171 gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9);
172 }
173}